• OpenGL的几何变换2之内观察立方体


    我想实现的一个场景是:一个立方体,相机的坐标在立方体的中心点,相机不变,立方体旋转,可以站在立方体中心点查看立方体内部。

    实际上就是立方体图像,这是在全景图片当作比较简单的方式,画面不会变形和扭曲,但是现在拍摄的全景图不会这样拍摄,更多的可点击先搞清楚全景视频是如何实现的查看

    其实就是当下炒得火热的VR视频,而现在呢简单一些,查看全景图片,VR和全景是有区别的,可以去了解下一张图看懂360°全景和VR的区别

    我们接下来全景图片,关于相机坐标和事物坐标,貌似都指向了下面几个函数:

    1、观察变换函数gluLookAt(),寻找观察点;

    2、旋转变换glRotatef(),全方位旋转立方体;

    3、平移变换函数gluTranslatef(),创建立方体使用;

    4、最后还少不了投影变换函数gluPerspective()

    这是单纯的画立方体,而不是加载本地图片贴图,贴图是我最终目的,后期再跟上,先附上这次的代码:

      1 #include <stdio.h>
      2 #include <math.h>
      3 #include <Windows.h>
      4 #include "includeglut.h"
      5 
      6 /*
      7  功能描述:使用OpenGL简单画立方体,在内部透视查看立方体内部
      8  */
      9 
     10 //输出模式,0-单缓存模式;非0双缓存模式
     11 #define OUTPUT_MODE 1
     12 
     13 //矩阵变换的坐标
     14 float oldx = 0;
     15 float oldy = 0;
     16 
     17 //交叉点的坐标
     18 int cx = 0;
     19 int cy = 0;
     20 
     21 int angle = 0;
     22 
     23 void init(void)
     24 {
     25     const GLfloat LightAmbient[4] = {0.1, 0.1, 0.1, 1.0};
     26     const GLfloat LightDiffuse[4] = {0, 0.8, 0.8, 1.0};
     27     const GLfloat LightPosition[4]={0,0,1,0};
     28 
     29     //glClearColor函数设置好清除颜色,glClear利用glClearColor函数设置好的当前清除颜色设置窗口颜色
     30     glClearColor(1.0, 1.0, 0.8, 1.0);
     31 
     32     glShadeModel(GL_SMOOTH);//选择单位或平滑阴影
     33     glEnable(GL_DEPTH_TEST);
     34 }
     35 
     36 #if (0)
     37 void display(void)
     38 {
     39     //printf("oldx=%f, oldy=%f
    ", oldx, oldy);
     40     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
     41 
     42     static float rotate = 0;
     43     static int times = 0;
     44 
     45     static float centerX = 0.0;
     46     static float centerY = 0.0;
     47     static float centerZ = 0.0;
     48     static bool add = TRUE;
     49 
     50     glMatrixMode(GL_MODELVIEW);
     51     glLoadIdentity();
     52     glPushMatrix();
     53     {
     54         gluLookAt(0, 0, -10.0f, centerX, centerY, centerZ, 0, 1, 0);
     55         glTranslatef(0, 0, -10.0);    //平移
     56         glScalef(1, 1, 1);        //缩放
     57     
     58         glRotatef(angle, 1, 1, 1);
     59 
     60         //将立方体的八个顶点保存到一个数组里面
     61         static const float vertex_list[][3] = 
     62         {
     63             //0        1        2
     64             -1.0f, -1.0f, -1.0f,//0
     65             1.0f, -1.0f, -1.0f,    //1
     66             -1.0f, 1.0f, -1.0f,    //2
     67             1.0f, 1.0f, -1.0f,    //3
     68             -1.0f, -1.0f, 1.0f,    //4
     69             1.0f, -1.0f, 1.0f,    //5
     70             -1.0f, 1.0f, 1.0f,    //6
     71             1.0f, 1.0f, 1.0f    //7
     72         };
     73 
     74         //将要使用的顶点的序号保存到一个数组里面
     75         static const GLint index_list[][2] = 
     76         {
     77             {0, 1}, 
     78             {2, 3}, 
     79             {4, 5}, 
     80             {6, 7}, 
     81             {0, 2}, 
     82             {1, 3}, 
     83             {4, 6}, 
     84             {5, 7}, 
     85             {0, 4}, 
     86             {1, 5}, 
     87             {7, 3}, 
     88             {2, 6}
     89         };
     90         float rgb[] = {0.1, 0.3, 1.0};
     91         int i,j;
     92         glBegin(GL_LINES);
     93         {
     94             for(i=0; i<12; ++i)    //12条线段
     95             {
     96                 for(j=0; j<2; ++j)    //每条线段2个顶点
     97                 {
     98                     printf("index : %d, [%d][%d], vertex : %.1f, %.1f, %.1f
    ", index_list[i][j], i, j, vertex_list[index_list[i][j]][0], vertex_list[index_list[i][j]][1], vertex_list[index_list[i][j]][2]);
     99                     glColor3f (rgb[0], rgb[1], rgb[2]); //画笔颜色
    100                     glVertex3fv(vertex_list[index_list[i][j]]);
    101 
    102                     rgb[0] += 0.2;
    103                     rgb[1] += 0.1;
    104                     rgb[2] -= 0.1;
    105                 }
    106             }
    107         }
    108         glEnd();
    109     }
    110     glPopMatrix();
    111 
    112     printf("centerX=%f, centerY=%f
    ", centerX, centerY);
    113     if (add)
    114     {
    115         centerX += 0.1;
    116         centerY += 0.1;
    117         centerZ += 0.1;
    118     } else {            
    119         centerX -= 0.1;
    120         centerY -= 0.1;
    121         centerZ -= 0.1;
    122     }
    123     if (centerX > 10)
    124     {
    125         add = FALSE;
    126     } else if (centerX < -10) {
    127         add = TRUE;
    128     }
    129     angle += 1;
    130     angle %= 360;
    131 
    132     if (OUTPUT_MODE == 0) {
    133         glFlush();//单缓存GLUT_SINGLE时使用
    134     } else {
    135         glutSwapBuffers();//因为使用的是双缓存GLUT_DOUBLE,所以这里必须要交换缓存才会显示
    136     }
    137 }
    138 
    139 #else
    140 void display(void)
    141 {
    142     //printf("oldx=%f, oldy=%f
    ", oldx, oldy);
    143     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    144 
    145     float rotatefs[][4] = {
    146         {90.0, 1.0, 0.0, 0.0},    //top
    147         {-90.0, 1.0, 0.0, 0.0},    //bottom
    148         {90.0, 0.0, 0.0, 1.0},    //front
    149         {-90.0, 0.0, 1.0, 0.0},    //left
    150         {-90.0, 0.0, 0.0, 1.0},    //back
    151         {90.0, 0.0, 1.0, 0.0},    //right
    152     };
    153 
    154     float translefs[][3] = {
    155         {0.0, 0.5, 0.0}, //top
    156         {0.0, -0.5, 0.0},//bottom
    157         {0.0, 0.0, -0.5},//front
    158         {-0.5, 0.0, 0.0},//left
    159         {0.0, 0.0, 0.5}, //back
    160         {0.5, 0.0, 0.0}     //right
    161     };
    162 
    163     glPushMatrix();    {
    164         glColor3f (0, 0, 0);
    165         glLoadIdentity();  //加载单位矩阵
    166         glTranslatef(0.0f,0.0f,-10.0f);
    167         glRectf(-1.0f, -1.0f, -0.5f, -0.5f);
    168     }
    169     glPopMatrix();
    170     
    171     glMatrixMode(GL_MODELVIEW);
    172     glLoadIdentity();  //加载单位矩阵
    173     glPushMatrix();    {
    174     glLoadIdentity();  //加载单位矩阵
    175     static float centerX = 0.0;
    176     static float centerY = 0.0;
    177     static float centerZ = 0.0;
    178     static bool add = TRUE;
    179         gluLookAt(0, 0, -10.0f, centerX, centerY, centerZ, 0, 1, 0);
    180         glTranslatef(0.0f,0.0f,-10.0f);
    181         glRotatef(angle, 0, 1, 0);
    182         glScalef(0.5, 0.5, 0.5);
    183         float rgb[] = {0.1, 0.3, 1.0};
    184         for(int i = 0; i < 6; i++) {
    185             glPushMatrix();    {
    186                 glTranslatef(translefs[i][0], translefs[i][1], translefs[i][2]);
    187                 glRotatef(rotatefs[i][0], rotatefs[i][1], rotatefs[i][2], rotatefs[i][3]);
    188                 //glScalef(-0.5, -0.5, -0.5);
    189                 glColor3f (rgb[0], rgb[1], rgb[2]); //画笔颜色
    190                 glRectf(-0.5f, -0.5f, 0.5f, 0.5f);
    191 
    192                 rgb[0] += 0.2;
    193                 rgb[1] += 0.1;
    194                 rgb[2] -= 0.1;
    195             }
    196             glPopMatrix();
    197         }
    198     }
    199     glPopMatrix();
    200 
    201     printf("centerX=%f, centerY=%f
    ", centerX, centerY);
    202     if (add)
    203     {
    204         centerX += 0.1;
    205         centerY += 0.1;
    206         centerZ += 0.1;
    207     } else {            
    208         centerX -= 0.1;
    209         centerY -= 0.1;
    210         centerZ -= 0.1;
    211     }
    212     if (centerX > 10)
    213     {
    214         add = FALSE;
    215     } else if (centerX < -10) {
    216         add = TRUE;
    217     }
    218     //如果通过鼠标控制,可以把下面两行代码注视掉,留着也没关系
    219     angle += 1;
    220     angle %= 360;
    221 
    222     if (OUTPUT_MODE == 0) {
    223         glFlush();//单缓存GLUT_SINGLE时使用
    224     } else {
    225         glutSwapBuffers();//因为使用的是双缓存GLUT_DOUBLE,所以这里必须要交换缓存才会显示
    226     }
    227 }
    228 
    229 #endif
    230 
    231 //处理鼠标点击
    232 void Mouse(int button, int state, int x, int y)
    233 {
    234     if(state == GLUT_DOWN) //第一次鼠标按下时,记录鼠标在窗口中的初始坐标
    235     {
    236         //记住鼠标点击后光标坐标
    237         cx = x;
    238         cy = y;
    239         //printf("Mouse: x=%d, y=%d, oldx=%f, oldy=%f
    ", x, y, oldx, oldy);
    240     }
    241 }
    242 
    243 //处理鼠标拖动
    244 void onMouseMove(int x, int y)
    245 {
    246     int offset = 5;
    247     if (cx <= 200 && y < cy) {//左半边区:顺时针手势
    248         angle -= offset;
    249         printf("angle1=%d
    ", angle);
    250     } else if (cx > 200 && y > cy) {//右半边区:顺时针手势
    251         angle -= offset;
    252         printf("angle2=%d
    ", angle);
    253     } else if (cx <= 200 && y > cy) {//左半边区:逆时针手势
    254         angle += offset;
    255         printf("angle3=%d
    ", angle);
    256     } else if (cx > 200 && y < cy) {//右半边区:逆时针手势
    257         angle += offset;
    258         printf("angle4=%d
    ", angle);
    259     }
    260     angle %= 360;
    261 
    262     //计算拖动后的偏移量,然后进行xy叠加减
    263     oldx += ((x - cx) * 0.01);
    264     oldy -= ((y - cy) * 0.01);
    265     //printf("Move: x=%d(%d)[%d], y=%d(%d)[%d], oldx=%f, oldy=%f
    ", x, cx, x-cx, y, cy, y-cy, oldx, oldy);
    266     glutPostRedisplay();
    267 
    268     //保存好当前拖放后光标坐标点
    269     cx = x;
    270     cy = y;
    271 }
    272 
    273 void reshape(int w, int h)
    274 {
    275     int offset = 10;
    276     int dis = (w > h ? h : w) - offset * 2;
    277     
    278     //配置显示物体屏幕的大小
    279     glViewport(offset, offset, (GLsizei)dis, (GLsizei)dis);
    280     printf("reshape: w=%d, h=%d, dis=%d
    ", w, h, dis);
    281 
    282     glMatrixMode(GL_PROJECTION);
    283     glLoadIdentity();
    284 
    285     //glOrtho(-1.5, 1.5, -1.5, 1.5, 0, 100);
    286     //gluOrtho2D(-1.5, 1.5, -1.5, 1.5);
    287     gluPerspective(90.0f, (GLfloat)w/(GLfloat)h, 0.1f, 100.0f);
    288 
    289     glMatrixMode(GL_MODELVIEW);
    290     glLoadIdentity();
    291 }
    292 
    293 int main(int argc, char *argv[])
    294 {
    295     glutInit(&argc, argv);
    296     
    297     glutInitDisplayMode(GLUT_RGB | (OUTPUT_MODE == 0 ? GLUT_SINGLE : GLUT_DOUBLE));
    298     glutInitWindowPosition(100, 100);
    299     glutInitWindowSize(400, 400);
    300     glutCreateWindow("第一个 OpenGL 程序");
    301 
    302     init();
    303     glutDisplayFunc(&display);
    304     glutIdleFunc(display);  //设置不断调用显示函数
    305     glutReshapeFunc(reshape);
    306     glutMouseFunc(Mouse);
    307     glutMotionFunc(onMouseMove);
    308     glutMainLoop();
    309     return 0;
    310 }

    没有录制,附上几张图

     

     

    最后附上代码执行文件链接: https://pan.baidu.com/s/1hsS3vEk 密码: tmdg

  • 相关阅读:
    zsh: command not found: mysql
    ReactiveX -Rx
    mac 安装mysql
    mac 完全卸载mysql
    gradle 编译OutOfMemoryError
    Nginx均衡负载(IP_HASH)未生效
    Tomcat集群+Nginx+Redis服务搭建
    Spring之SpringMVC的RequestToViewNameTranslator(源码)分析
    Spring之SpringMVC的MethodNameResolver(源码)分析
    Spring之SpringMVC前端控制器DispatcherServlet(源码)分析
  • 原文地址:https://www.cnblogs.com/1024Planet/p/5661240.html
Copyright © 2020-2023  润新知