• 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;
    }

      

  • 相关阅读:
    批处理命令之实现修改环境变量的值
    【hihocoder 1304】搜索一·24点
    【hihocoder 1297】数论四·扩展欧几里德
    【hihocoder 1298】 数论五·欧拉函数
    【hihocoder 1303】模线性方程组
    C语言如何动态分配二维数组
    Istream中的函数
    string 与 char * 转换
    boost 系列 1:boost 直接使用
    glog功能介绍 一分钟 51CTO技术博客
  • 原文地址:https://www.cnblogs.com/LieYanAnYing/p/12152603.html
Copyright © 2020-2023  润新知