zoukankan      html  css  js  c++  java
  • 3D_solarSys

    计算机图形学_3DsolarSys

    一、软件功能

           1、实现3D太阳系,有太阳、土星、土星环、地球、月球、天王星、海王星、火星。其中土星、地球、天王星、海王星、火星绕着太阳转,土星环绕着土星转,月球绕着地球转。

           2可以鼠标左、中、右任意键拖动太阳系观察。

           3连续点击鼠标中键,太阳系整体绕z轴开始旋转并且速度加一;点击鼠标右键,连续点击中键,太阳系整体绕z轴开始旋转并且速度加一;点击鼠标左键,太阳系会立马停止转动。

           4、按下键盘,O:取消轨道,P:显示轨道,U:视角上升,I:视角下降,Y:显示数轴,N:取消数轴,C:显示字符,V:取消字符,WSAD:控制相机移动。

           5实现了太阳光照效果。

           6、实现了星光。

    二、实现

           myDisplay()显示函数,myIdle()设置全局回调函数,mouse()设置鼠标点击事件监听,motion()设置鼠标滑动事件监听,keyboard()设置键盘事件监听,selectFont()设置字体,drawCNString()生成中文字体。

           实现星系

                  glEnable(GL_DEPTH_TEST);开启更新深度缓冲区。利用glutWireSphere()绘制线形球体或者利用glutSolidSphere()绘制实体球体。在绘制行星时需要进行坐标原点的迁移glTranslatef(),每次绘制的行星都是在上一个矩阵的基础上进行的偏移,所以在绘制行星前需要glPushMatrix()将太阳坐标矩阵压栈,在将要绘制行星时先将太阳坐标矩阵弹栈glPopMatrix(),而在绘制月球或者土星环时则无需弹栈。

           实现鼠标拖动

                  void motion(int x, int y)传入鼠标参数值,anglex += 360 * (GLfloat)deltay / (GLfloat)WinW根据屏幕上鼠标滑动的距离来设置旋转的角度。

           实现鼠标控制旋转

                  void mouse(int button, int state, int x, int y)传入鼠标参数值,if (button == GLUT_RIGHT_BUTTON&&state == GLUT_DOWN)判断哪一个键和状态,{isy = 0.0; isz = 1.0;}决定太阳是绕着哪个轴旋转或者rote = 0使其停止旋转。

           实现键盘控制

                  void keyboard(unsigned char key, int x, int y)传入键盘参数,利用switch语句判断key类型,显示和取消类型的控制利用设置控制条件将其实现代码写入if语句中,视角的变换是控制glLookAt的eyez值实现的,控制相机移动是控制eyex和eyey值实现的。

           实现太阳光照

                  glLightfv(GL_LIGHT0, GL_POSITION, sun_light_position);

                  glLightfv(GL_LIGHT0, GL_AMBIENT,   sun_light_ambient);

                  glLightfv(GL_LIGHT0, GL_DIFFUSE,   sun_light_diffuse);

                  glLightfv(GL_LIGHT0, GL_SPECULAR, sun_light_specular);

                  定义光源位置、环境光、漫反射光、镜面光,{ glEnable(GL_LIGHT0); glEnable(GL_LIGHTING); }开启光源。

                  GLfloat earth_mat_ambient[]   = {1.0f, 0.5f, 0.31f, 1.0f};  //定义材质的环境光颜色,偏蓝色

                  GLfloat earth_mat_diffuse[]   = {1.0f, 0.4f, 0.2f, 1.0f};  //定义材质的漫反射光颜色,偏蓝色

                  GLfloat earth_mat_specular[] = {1.0f, 0.0f, 0.0f, 1.0f};   //定义材质的镜面反射光颜色,红色

                  GLfloat earth_mat_emission[] = {0.0f, 0.0f, 0.0f, 1.0f};   //定义材质的辐射光颜色,为0

                  GLfloat earth_mat_shininess   = 30.0f;     //定义太阳光强

                  定义星球的表面光照情况。

           实现星光

                  glColor3f((rand()/(GLfloat)RAND_MAX),(rand()/(GLfloat)RAND_MAX),(rand()/(GLfloat)RAND_MAX));

            glVertex3f((rand()/(GLfloat)RAND_MAX)*pow(-1,rand())*700,(rand()/(GLfloat)RAND_MAX)*pow(-1,rand())*700,(rand()/(GLfloat)RAND_MAX)*pow(-1,rand())*700);

                  随机画点颜色和位置

    三、运行截图

     

    四、代码

    #include<Windows.h>
    #include<GLglut.h>
    #include<iostream>
    #include<stdlib.h>
    #include<math.h>
    //太阳、地球和月亮
    //假设每个月都是30天
    //一年12个月,共是360天
    #define N  999
    using namespace std;
    static int day = 360; // day的变化:从0到359
    static float PI = 3.14159;
    
    
    GLfloat roate = 0.0;// set rote of roate ying yu bu hao  bu zhuang le 设置旋转速率
    GLfloat rote = 0.0;//shezhi旋转角度
    GLfloat isy = 0.0;//太阳绕y轴旋转
    GLfloat isz = 0.0;//太阳绕z轴旋转
    GLfloat hasOrbit = 1.0f;
    GLfloat hasCoordinate = 1.0f;
    GLfloat hasCharacter = 1.0f;
    GLfloat eyehight = 50.0;
    GLfloat eyex = 0.0f;
    GLfloat eyey = -600;
    
    GLfloat anglex = 0.0;//X 轴旋转
    GLfloat angley = 0.0;//Y 轴旋转
    GLfloat anglez = 0.0;//Z 轴旋转
    GLint WinW = 1000;
    GLint WinH = 1000;
    GLfloat oldx;//当左键按下时记录鼠标坐标
    GLfloat oldy;
    
    void selectFont(int size, int charset, const char*face);
    void drawCNString(const char* str);
    
    void myDisplay(void)
    {
        glEnable(GL_DEPTH_TEST);
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
        glMatrixMode(GL_PROJECTION);
        glLoadIdentity();
        gluPerspective(75, 1, 1, 1000);
    
        glRotatef(anglex, 1.0, 0.0, 0.0);
        glRotatef(angley, 0.0, 1.0, 0.0);
        glRotatef(anglez, 0.0, 0.0, 1.0);
        rote += roate;
        glMatrixMode(GL_MODELVIEW);
        glLoadIdentity();
        gluLookAt(eyex, eyey, eyehight, 0, 0, 0, 0, 0, 1.0);
        glPushMatrix();
    //    gluLookAt(0.0, 0.0, 5.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
    
        // 定义太阳光源,它是一种白色的光源
        {
            GLfloat sun_light_position[] = {0.0f, 0.0f, 0.0f, 1.0f}; //光源的位置在世界坐标系圆心,齐次坐标形式
            GLfloat sun_light_ambient[]   = {0.0f, 0.0f, 0.0f, 1.0f}; //RGBA模式的环境光,为0
            GLfloat sun_light_diffuse[]   = {1.0f, 1.0f, 1.0f, 1.0f}; //RGBA模式的漫反射光,全白光
            GLfloat sun_light_specular[] = {1.0f, 1.0f, 1.0f, 1.0f};  //RGBA模式下的镜面光 ,全白光
            glLightfv(GL_LIGHT0, GL_POSITION, sun_light_position);
            glLightfv(GL_LIGHT0, GL_AMBIENT,   sun_light_ambient);
            glLightfv(GL_LIGHT0, GL_DIFFUSE,   sun_light_diffuse);
            glLightfv(GL_LIGHT0, GL_SPECULAR, sun_light_specular);
    
            //开启光源
            glEnable(GL_LIGHT0);
            glEnable(GL_LIGHTING);
            glEnable(GL_DEPTH_TEST);
        }
        if(hasCharacter==1.0f)
        {
            /*在绘制部分调用字体函数,写中文字*/
            GLfloat sun_mat_emission[] = {0.1, 0.6, 0.3, 1.0f};   //定义材质的辐射广颜色
            glMaterialfv(GL_FRONT, GL_EMISSION,   sun_mat_emission);
    
            selectFont(1, GB2312_CHARSET, "楷体GB2312");//设置字体
            glRasterPos3f(-400, 0, -400);//定位首字
            drawCNString("");//写字
            selectFont(15, GB2312_CHARSET, "楷体GB2312");//设置字体
            glRasterPos3f(-400, 0, 390);//定位首字
            drawCNString("V:取消字体");//写字
            selectFont(15, GB2312_CHARSET, "楷体GB2312");//设置字体
            glRasterPos3f(-400, 0, 373);//定位首字
            drawCNString("C:显示字体");//写字
            selectFont(15, GB2312_CHARSET, "楷体GB2312");//设置字体
            glRasterPos3f(-400, 0, 356);//定位首字
            drawCNString("O:取消轨道");//写字
            selectFont(15, GB2312_CHARSET, "楷体GB2312");//设置字体
            glRasterPos3f(-400, 0, 339);//定位首字
            drawCNString("P:显示轨道");//写字
            selectFont(15, GB2312_CHARSET, "楷体GB2312");//设置字体
            glRasterPos3f(-400, 0, 322);//定位首字
            drawCNString("I:下降视角");//写字
            selectFont(15, GB2312_CHARSET, "楷体GB2312");//设置字体
            glRasterPos3f(-400, 0, 305);//定位首字
            drawCNString("U:上升视角");//写字
            selectFont(15, GB2312_CHARSET, "楷体GB2312");//设置字体
            glRasterPos3f(-400, 0, 288);//定位首字
            drawCNString("Y:显示标轴");//写字
            selectFont(15, GB2312_CHARSET, "楷体GB2312");//设置字体
            glRasterPos3f(-400, 0, 271);//定位首字
            drawCNString("N:取消标轴");//写字
            selectFont(15, GB2312_CHARSET, "楷体GB2312");//设置字体
            glRasterPos3f(-400, 0, 254);//定位首字
            drawCNString("A:向左移动");//写字
            selectFont(15, GB2312_CHARSET, "楷体GB2312");//设置字体
            glRasterPos3f(-400, 0, 237);//定位首字
            drawCNString("D:向右移动");//写字
            selectFont(15, GB2312_CHARSET, "楷体GB2312");//设置字体
            glRasterPos3f(-400, 0, 220);//定位首字
            drawCNString("W:向前移动");//写字
            selectFont(15, GB2312_CHARSET, "楷体GB2312");//设置字体
            glRasterPos3f(-400, 0, 203);//定位首字
            drawCNString("S:向后移动");//写字
            selectFont(15, GB2312_CHARSET, "楷体GB2312");//设置字体
            glRasterPos3f(-400, 0, 186);//定位首字
            drawCNString("左键:移动行星");//写字
            selectFont(15, GB2312_CHARSET, "楷体GB2312");//设置字体
            glRasterPos3f(-400, 0, 169);//定位首字
            drawCNString("中键:绕X旋转");//写字
            selectFont(15, GB2312_CHARSET, "楷体GB2312");//设置字体
            glRasterPos3f(-400, 0, 152);//定位首字
            drawCNString("右键:绕Y旋转");//写字
        }
        {//画星光
            int i;
            glPointSize(4);
            glPopMatrix();
            glBegin(GL_POINTS);
            for(i=0; i<10; i++)
            {
                glColor3f((rand()/(GLfloat)RAND_MAX),(rand()/(GLfloat)RAND_MAX),(rand()/(GLfloat)RAND_MAX));
                glVertex3f((rand()/(GLfloat)RAND_MAX)*pow(-1,rand())*700,(rand()/(GLfloat)RAND_MAX)*pow(-1,rand())*700,(rand()/(GLfloat)RAND_MAX)*pow(-1,rand())*700);
            }
            glEnd();
        }
        {
            GLfloat sun_mat_ambient[]   = {0.0f, 0.0f, 0.0f, 1.0f};  //定义材质的环境光颜色,为0
            GLfloat sun_mat_diffuse[]   = {0.0f, 0.0f, 0.0f, 1.0f};  //定义材质的漫反射光颜色,为0
            GLfloat sun_mat_specular[] = {0.0f, 0.0f, 0.0f, 1.0f};   //定义材质的镜面反射光颜色,为0
            GLfloat sun_mat_emission[] = {0.8f, 0.0f, 0.0f, 1.0f};   //定义材质的辐射广颜色,为偏红色
            GLfloat sun_mat_shininess   = 0.0f;
            glMaterialfv(GL_FRONT, GL_AMBIENT,    sun_mat_ambient);
            glMaterialfv(GL_FRONT, GL_DIFFUSE,    sun_mat_diffuse);
            glMaterialfv(GL_FRONT, GL_SPECULAR,   sun_mat_specular);
            glMaterialfv(GL_FRONT, GL_EMISSION,   sun_mat_emission);
            glMaterialf (GL_FRONT, GL_SHININESS, sun_mat_shininess);
            //绘制红色的“太阳”
            glColor3f(1.0f, 0.0f, 0.0f);
            glRotatef(rote, 0.0f, isy, isz);
            glutWireSphere(100, 250, 250);
            glPushMatrix();//将太阳的变换矩阵压入栈
        }
        {
            GLfloat earth_mat_ambient[]   = {1.0f, 0.5f, 0.31f, 1.0f};  //定义材质的环境光颜色,偏蓝色
            GLfloat earth_mat_diffuse[]   = {1.0f, 0.4f, 0.2f, 1.0f};  //定义材质的漫反射光颜色,偏蓝色
            GLfloat earth_mat_specular[] = {1.0f, 0.0f, 0.0f, 1.0f};   //定义材质的镜面反射光颜色,棕色
            GLfloat earth_mat_emission[] = {0.0f, 0.0f, 0.0f, 1.0f};   //定义材质的辐射光颜色,为0
            GLfloat earth_mat_shininess   = 50.0f;
            glMaterialfv(GL_FRONT, GL_AMBIENT,    earth_mat_ambient);
            glMaterialfv(GL_FRONT, GL_DIFFUSE,    earth_mat_diffuse);
            glMaterialfv(GL_FRONT, GL_SPECULAR,   earth_mat_specular);
            glMaterialfv(GL_FRONT, GL_EMISSION,   earth_mat_emission);
            glMaterialf (GL_FRONT, GL_SHININESS, earth_mat_shininess);
            //绘制棕色的“土星”
            glColor3f(0.7f, 0.5f, 0.0f);
            glRotatef((((day+300) / 360.0)*360.0)*2, 0.0f, 0.0f, -1.0f);
            glTranslatef(0.0f, 150, 0.0f);
            glutSolidSphere(20, 30, 10);
    
    //        glBegin(GL_LINE_STRIP);
    //        for (int i = 0; i < 361; i++)
    //        {
    //            glVertex3f(20 * (float)sin(i * PI / 180), 0, 20 * (float)cos(i * PI / 180));
    //        }
    //        glEnd();
        }
        {
            GLfloat earth_mat_ambient[]   = {1.0f, 0.5f, 0.31f, 1.0f};  //定义材质的环境光颜色,骗蓝色
            GLfloat earth_mat_diffuse[]   = {1.0f, 0.4f, 0.2f, 1.0f};  //定义材质的漫反射光颜色,偏蓝色
            GLfloat earth_mat_specular[] = {1.0f, 0.0f, 0.0f, 1.0f};   //定义材质的镜面反射光颜色,红色
            GLfloat earth_mat_emission[] = {0.0f, 0.0f, 0.0f, 1.0f};   //定义材质的辐射光颜色,为0
            GLfloat earth_mat_shininess   = 30.0f;
            glMaterialfv(GL_FRONT, GL_AMBIENT,    earth_mat_ambient);
            glMaterialfv(GL_FRONT, GL_DIFFUSE,    earth_mat_diffuse);
            glMaterialfv(GL_FRONT, GL_SPECULAR,   earth_mat_specular);
            glMaterialfv(GL_FRONT, GL_EMISSION,   earth_mat_emission);
            glMaterialf (GL_FRONT, GL_SHININESS, earth_mat_shininess);
            //绘制棕色的“土星环”
            glColor3f(0.7f, 0.5f, 0.0f);
            glRotatef((day+200) / 360.0*360.0, 0.0f, 0.0f, -1.0f);
            glTranslatef(0.0f, 0.0f, 0.0f);
            glRotatef(10.0, 0.0, 0.0, 1.0);
            glutWireTorus(0.5, 30, 20, 20);
        }
        {
            GLfloat earth_mat_ambient[]   = {0.0f, 0.0f, 1.0f, 1.0f};  //定义材质的环境光颜色,骗蓝色
            GLfloat earth_mat_diffuse[]   = {0.0f, 0.0f, 0.5f, 1.0f};  //定义材质的漫反射光颜色,偏蓝色
            GLfloat earth_mat_specular[] = {1.0f, 0.0f, 0.0f, 1.0f};   //定义材质的镜面反射光颜色,红色
            GLfloat earth_mat_emission[] = {0.0f, 0.0f, 0.0f, 1.0f};   //定义材质的辐射光颜色,为0
            GLfloat earth_mat_shininess   = 40.0f;
            glMaterialfv(GL_FRONT, GL_AMBIENT,    earth_mat_ambient);
            glMaterialfv(GL_FRONT, GL_DIFFUSE,    earth_mat_diffuse);
            glMaterialfv(GL_FRONT, GL_SPECULAR,   earth_mat_specular);
            glMaterialfv(GL_FRONT, GL_EMISSION,   earth_mat_emission);
            glMaterialf (GL_FRONT, GL_SHININESS, earth_mat_shininess);
            //绘制蓝色的“地球”
            glPopMatrix();//太阳的变换矩阵弹栈
            glPushMatrix();
            glColor3f(0.0f, 0.0f, 1.0f);
            glRotatef(day / 360.0*360.0, 0.0f, 0.0f, -1.0f);
            glTranslatef(250, 0.0f, 0.0f);
            glutWireSphere(10, 30, 10);
        }
        {
                GLfloat earth_mat_ambient[]   = {0.156, 0.941, 0.47, 1.0f};  //定义材质的环境光颜色,骗蓝色
                GLfloat earth_mat_diffuse[]   = {0.156, 0.941, 0.47, 1.0f};  //定义材质的漫反射光颜色,偏蓝色
                GLfloat earth_mat_specular[] = {1.0f, 0.0f, 0.0f, 1.0f};   //定义材质的镜面反射光颜色,红色
                GLfloat earth_mat_emission[] = {0.0f, 0.0f, 0.0f, 1.0f};   //定义材质的辐射光颜色,为0
                GLfloat earth_mat_shininess   = 30.0f;
                glMaterialfv(GL_FRONT, GL_AMBIENT,    earth_mat_ambient);
                glMaterialfv(GL_FRONT, GL_DIFFUSE,    earth_mat_diffuse);
                glMaterialfv(GL_FRONT, GL_SPECULAR,   earth_mat_specular);
                glMaterialfv(GL_FRONT, GL_EMISSION,   earth_mat_emission);
                glMaterialf (GL_FRONT, GL_SHININESS, earth_mat_shininess);
                //绘制黄色的“月亮”
                glColor3f(0.156, 0.941, 0.47);
                glRotatef(day / 30.0*360.0 - day / 360.0*360.0, 0.0f, 0.0f, -1.0f);
                glRotatef(day / 30.0*360.0, 0.0f, 0.0f, -1.0f);
                glTranslatef(15, 0.0f, 0.0f);
                glutSolidSphere(4, 100, 100);
        }
    
        GLfloat earth_mat_ambient[3][4]   = {{0.9, 0.941, 0.47, 1.0f},{0.0f, 0.941, 0.235, 1.0f},{1.0f, 0.6f, 1.0f, 1.0f}};  //定义材质的环境光颜色,骗蓝色
        GLfloat earth_mat_diffuse[3][4]   = {{0.57, 0.941, 0.47, 1.0f},{0.0f, 0.941, 0.235, 1.0f},{1.0f, 0.6f, 1.0, 1.0f}};  //定义材质的漫反射光颜色,偏蓝色
        GLfloat earth_mat_specular[3][4] = {{1.0f, 0.0f, 0.0f, 1.0f},{1.0f, 0.0f, 0.0f, 1.0f},{1.0f, 0.0f, 0.0f, 1.0f}};   //定义材质的镜面反射光颜色,红色
        GLfloat earth_mat_emission[3][4] = {{0.0f, 0.0f, 0.0f, 1.0f},{0.0f, 0.0f, 0.0f, 1.0f},{0.0f, 0.0f, 0.0f, 1.0f}};   //定义材质的辐射光颜色,为0
        GLfloat earth_mat_shininess[3] = {30.0f,20.0f,10.0f};
        GLfloat glColor[3][3] = {{0.47, 0.941, 0.47},{0.0f, 0.941, 0.235},{1.0f, 0.6f, 1.0f}};
        GLfloat glTranslate[3][3] = {{250, -250, 0.0f},{-240, 230, 0.0f},{300, 300, 0.0f}};
        GLfloat radius[3][3] ={{15, 30, 10},{8, 30, 10},{12, 30, 10}};
        GLfloat speed[3] = {(day-100) / 360.0*360.0,(day-150) / 360.0*360.0,(day-200) / 360.0*360.0};
        for(int i=0;i<3;i++)
        {
            glMaterialfv(GL_FRONT, GL_AMBIENT,    earth_mat_ambient[i]);
            glMaterialfv(GL_FRONT, GL_DIFFUSE,    earth_mat_diffuse[i]);
            glMaterialfv(GL_FRONT, GL_SPECULAR,   earth_mat_specular[i]);
            glMaterialfv(GL_FRONT, GL_EMISSION,   earth_mat_emission[i]);
            glMaterialf (GL_FRONT, GL_SHININESS, earth_mat_shininess[i]);
            //绘制蓝色的“地球”
            glPopMatrix();//太阳的变换矩阵弹栈
            glPushMatrix();
            glColor3f(glColor[i][0],glColor[i][1],glColor[i][2]);
            glRotatef(speed[i], 0.0f, 0.0f, -1.0f);
            glTranslatef(glTranslate[i][0],glTranslate[i][1],glTranslate[i][2]);
            glutSolidSphere(radius[i][0],radius[i][1],radius[i][2]);
        }
        //画行星轨道
        if(hasOrbit==1.0f)
        {
            glPopMatrix();
            glutWireTorus(0.1, 150, 10, 64);
            glutWireTorus(0.1, 353.55, 10, 64);
            glutWireTorus(0.1, 332.42, 10, 64);
            glutWireTorus(0.1, 424.26, 10, 64);
            glutWireTorus(0.1, 250, 10, 64);
        }
        //画坐标轴
        if(hasCoordinate==1.0f)
        {
            const int AXES_LEN = 300;
            const int ARROW_LEN = 100;
            const int ARROW_RADIUS = 10;
    
            GLUquadricObj *objCylinder = gluNewQuadric();
            //确定坐标系原点
            glPushMatrix();
            glColor3f(1.0f, 1.0f, 1.0f);
            glutSolidSphere(10, 20, 20);
            glPopMatrix();
    
            glPushMatrix();
            glColor3f(1.0f, 0.0f, 0.0f);
            glutSolidSphere(0.25, 6, 6);
            gluCylinder(objCylinder, 5, 5, AXES_LEN, 10, 5); //z
            glTranslatef(0, 0, AXES_LEN);
            gluCylinder(objCylinder, ARROW_RADIUS, 0, ARROW_LEN, 10, 5); //z arrow
            glPopMatrix();
    
            glPushMatrix();
            glColor3f(0.0f, 1.0f, 0.0f);
            glRotatef(90, 1.0, 0.0, 0.0);
            gluCylinder(objCylinder, 5, 5, AXES_LEN, 10, 5); //Y
            glTranslatef(0, 0, AXES_LEN);
            gluCylinder(objCylinder, ARROW_RADIUS, 0, ARROW_LEN, 10, 5); //Y arrow
            glPopMatrix();
    
            glPushMatrix();
            glColor3f(0.0f, 0.0f, 1.0f);
            glRotatef(90, 0.0, 1.0, 0.0);
            gluCylinder(objCylinder, 5, 5, AXES_LEN, 10, 5); //X
            glTranslatef(0, 0, AXES_LEN);
            gluCylinder(objCylinder, ARROW_RADIUS, 0, ARROW_LEN, 10, 5); //X arrow
            glPopMatrix();
        }
        glFlush();
        glutSwapBuffers();
        }
        void myIdle(void)
        {
        Sleep(50);
        ++day;
        if (day >= 360)
        day = 0;
        myDisplay();
    }
    
    void mouse(int button, int state, int x, int y)
    {
        if (button == GLUT_LEFT_BUTTON&&state == GLUT_DOWN)
        {
                roate = 0;
                rote = 0;
                oldx = x;//当左键按下时记录鼠标坐标
                oldy = y;
        }
        if (button == GLUT_MIDDLE_BUTTON&&state == GLUT_DOWN)
        {
                isy = 0.0;
                isz = 1.0;
                oldx = x;//当左键按下时记录鼠标坐标
                oldy = y;
                roate += 2.0f;
        }
        if (button == GLUT_RIGHT_BUTTON&&state == GLUT_DOWN)
        {
                isy = 1.0;
                isz = 0.0;
                oldx = x;//当左键按下时记录鼠标坐标
                oldy = y;
                roate += 2.0f;
        }
    }
    
    void motion(int x, int y)
    {
        GLint deltax = oldx - x;
        GLint deltay = oldy - y;
        anglex += 360 * (GLfloat)deltay / (GLfloat)WinW;//根据屏幕上鼠标滑动的距离来设置旋转的角度
        angley += 360 * (GLfloat)deltax / (GLfloat)WinH;
    //    anglez += 360 * (GLfloat)deltay / (GLfloat)WinH;
        oldx = x;//记录此时的鼠标坐标,更新鼠标坐标
        oldy = y;//若是没有这两句语句,滑动是旋转会变得不可控
        glutPostRedisplay();
        glutPostRedisplay();
    }
    
    void keyboard(unsigned char key, int x, int y)
    {
        switch(key)
        {
        case 'o':
        case'O':
            hasOrbit = 0.0f;
            break;
        case 'p':
        case 'P':
            hasOrbit = 1.0f;
            break;
        case 'y':
        case'Y':
            hasCoordinate = 1.0f;
            break;
        case 'n':
        case 'N':
            hasCoordinate = 0.0f;
            break;
        case 'c':
        case'C':
            hasCharacter = 1.0f;
            break;
        case 'v':
        case 'V':
            hasCharacter = 0.0f;
            break;
        case 'i':
        case 'I':
            eyehight-=10;
            break;
        case 'u':
        case 'U':
            eyehight+=10;
            break;
        case 'w':
        case 'W':
            eyey+=10;
            break;
        case 's':
        case 'S':
            eyey-=10;
            break;
        case 'a':
        case 'A':
            eyex-=10;
            break;
        case 'd':
        case 'D':
            eyex+=10;
            break;
        }
    }
    
    //选择字体函数
    void selectFont(int size, int charset, const char*face)
    {
        HFONT hFont = CreateFontA(size, 0, 0, 0, FW_MEDIUM, 0, 0, 0,
            charset, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
            DEFAULT_QUALITY, DEFAULT_PITCH | FF_SWISS, face);
    
        HFONT hOldFont = (HFONT)SelectObject(wglGetCurrentDC(), hFont);
        DeleteObject(hOldFont);
    }
    
    //生成中文字体
    void drawCNString(const char* str)
    {
        int len, i;
        wchar_t* wstring;
        HDC hDC = wglGetCurrentDC();
        GLuint list = glGenLists(1);
        //计算字符的个数
        //如果是双字节字符的(比如中文字符),两个字节才算一个字符
        //否则一个字节算一个字符
        len = 0;
        for (i = 0; str[i] != ''; ++i)
        {
            if (IsDBCSLeadByte(str[i]))
                ++i;
            ++len;
        }
        //将混合字符转化为宽字符
        wstring = (wchar_t*)malloc((len + 1) * sizeof(wchar_t));
        MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, str, -1, wstring, len);
        wstring[len] = L'';
        //逐个输出字符
        for (i = 0; i < len; ++i)
        {
            wglUseFontBitmapsW(hDC, wstring[i], 1, list);
            glCallList(list);
        }
        //回收所有临时资源
        free(wstring);
        glDeleteLists(list, 1);
    }
    
    int main(int argc, char *argv[])
    {
        glutInit(&argc, argv);
        glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE);
        glutInitWindowPosition(200, 100);
        glutInitWindowSize(800, 1200);
        glutCreateWindow("I love OpenGL");
        glutDisplayFunc(&myDisplay);
        glutMouseFunc(mouse);
        glutMotionFunc(motion);
        glutKeyboardFunc(keyboard);
        glutIdleFunc(&myIdle);
        glutMainLoop();
        return 0;
    }

      

  • 相关阅读:
    Security and Cryptography in Python
    Security and Cryptography in Python
    Security and Cryptography in Python
    Security and Cryptography in Python
    Security and Cryptography in Python
    Security and Cryptography in Python
    Security and Cryptography in Python
    《EffectiveJava中文第二版》 高清PDF下载
    《MoreEffectiveC++中文版》 pdf 下载
    《啊哈c语言》 高清 PDF 下载
  • 原文地址:https://www.cnblogs.com/LieYanAnYing/p/12152603.html
Copyright © 2011-2022 走看看