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

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

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

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

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

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

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

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

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

 #include <stdio.h>
#include <math.h>
#include <Windows.h>
#include "include\glut.h" /*
功能描述:使用OpenGL简单画立方体,在内部透视查看立方体内部
*/ //输出模式,0-单缓存模式;非0双缓存模式
#define OUTPUT_MODE 1 //矩阵变换的坐标
float oldx = ;
float oldy = ; //交叉点的坐标
int cx = ;
int cy = ; int angle = ; void init(void)
{
const GLfloat LightAmbient[] = {0.1, 0.1, 0.1, 1.0};
const GLfloat LightDiffuse[] = {, 0.8, 0.8, 1.0};
const GLfloat LightPosition[]={,,,}; //glClearColor函数设置好清除颜色,glClear利用glClearColor函数设置好的当前清除颜色设置窗口颜色
glClearColor(1.0, 1.0, 0.8, 1.0); glShadeModel(GL_SMOOTH);//选择单位或平滑阴影
glEnable(GL_DEPTH_TEST);
} #if (0)
void display(void)
{
//printf("oldx=%f, oldy=%f\n", oldx, oldy);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); static float rotate = ;
static int times = ; static float centerX = 0.0;
static float centerY = 0.0;
static float centerZ = 0.0;
static bool add = TRUE; glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glPushMatrix();
{
gluLookAt(, , -10.0f, centerX, centerY, centerZ, , , );
glTranslatef(, , -10.0); //平移
glScalef(, , ); //缩放 glRotatef(angle, , , ); //将立方体的八个顶点保存到一个数组里面
static const float vertex_list[][] =
{
//0 1 2
-1.0f, -1.0f, -1.0f,//
1.0f, -1.0f, -1.0f, //
-1.0f, 1.0f, -1.0f, //
1.0f, 1.0f, -1.0f, //
-1.0f, -1.0f, 1.0f, //
1.0f, -1.0f, 1.0f, //
-1.0f, 1.0f, 1.0f, //
1.0f, 1.0f, 1.0f //
}; //将要使用的顶点的序号保存到一个数组里面
static const GLint index_list[][] =
{
{, },
{, },
{, },
{, },
{, },
{, },
{, },
{, },
{, },
{, },
{, },
{, }
};
float rgb[] = {0.1, 0.3, 1.0};
int i,j;
glBegin(GL_LINES);
{
for(i=; i<; ++i) //12条线段
{
for(j=; j<; ++j) //每条线段2个顶点
{
printf("index : %d, [%d][%d], vertex : %.1f, %.1f, %.1f\n", index_list[i][j], i, j, vertex_list[index_list[i][j]][], vertex_list[index_list[i][j]][], vertex_list[index_list[i][j]][]);
glColor3f (rgb[], rgb[], rgb[]); //画笔颜色
glVertex3fv(vertex_list[index_list[i][j]]); rgb[] += 0.2;
rgb[] += 0.1;
rgb[] -= 0.1;
}
}
}
glEnd();
}
glPopMatrix(); printf("centerX=%f, centerY=%f\n", centerX, centerY);
if (add)
{
centerX += 0.1;
centerY += 0.1;
centerZ += 0.1;
} else {
centerX -= 0.1;
centerY -= 0.1;
centerZ -= 0.1;
}
if (centerX > )
{
add = FALSE;
} else if (centerX < -) {
add = TRUE;
}
angle += ;
angle %= ; if (OUTPUT_MODE == ) {
glFlush();//单缓存GLUT_SINGLE时使用
} else {
glutSwapBuffers();//因为使用的是双缓存GLUT_DOUBLE,所以这里必须要交换缓存才会显示
}
} #else
void display(void)
{
//printf("oldx=%f, oldy=%f\n", oldx, oldy);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); float rotatefs[][] = {
{90.0, 1.0, 0.0, 0.0}, //top
{-90.0, 1.0, 0.0, 0.0}, //bottom
{90.0, 0.0, 0.0, 1.0}, //front
{-90.0, 0.0, 1.0, 0.0}, //left
{-90.0, 0.0, 0.0, 1.0}, //back
{90.0, 0.0, 1.0, 0.0}, //right
}; float translefs[][] = {
{0.0, 0.5, 0.0}, //top
{0.0, -0.5, 0.0},//bottom
{0.0, 0.0, -0.5},//front
{-0.5, 0.0, 0.0},//left
{0.0, 0.0, 0.5}, //back
{0.5, 0.0, 0.0} //right
}; glPushMatrix(); {
glColor3f (, , );
glLoadIdentity(); //加载单位矩阵
glTranslatef(0.0f,0.0f,-10.0f);
glRectf(-1.0f, -1.0f, -0.5f, -0.5f);
}
glPopMatrix(); glMatrixMode(GL_MODELVIEW);
glLoadIdentity(); //加载单位矩阵
glPushMatrix(); {
glLoadIdentity(); //加载单位矩阵
static float centerX = 0.0;
static float centerY = 0.0;
static float centerZ = 0.0;
static bool add = TRUE;
gluLookAt(, , -10.0f, centerX, centerY, centerZ, , , );
glTranslatef(0.0f,0.0f,-10.0f);
glRotatef(angle, , , );
glScalef(0.5, 0.5, 0.5);
float rgb[] = {0.1, 0.3, 1.0};
for(int i = ; i < ; i++) {
glPushMatrix(); {
glTranslatef(translefs[i][], translefs[i][], translefs[i][]);
glRotatef(rotatefs[i][], rotatefs[i][], rotatefs[i][], rotatefs[i][]);
//glScalef(-0.5, -0.5, -0.5);
glColor3f (rgb[], rgb[], rgb[]); //画笔颜色
glRectf(-0.5f, -0.5f, 0.5f, 0.5f); rgb[] += 0.2;
rgb[] += 0.1;
rgb[] -= 0.1;
}
glPopMatrix();
}
}
glPopMatrix(); printf("centerX=%f, centerY=%f\n", centerX, centerY);
if (add)
{
centerX += 0.1;
centerY += 0.1;
centerZ += 0.1;
} else {
centerX -= 0.1;
centerY -= 0.1;
centerZ -= 0.1;
}
if (centerX > )
{
add = FALSE;
} else if (centerX < -) {
add = TRUE;
}
//如果通过鼠标控制,可以把下面两行代码注视掉,留着也没关系
angle += ;
angle %= ; if (OUTPUT_MODE == ) {
glFlush();//单缓存GLUT_SINGLE时使用
} else {
glutSwapBuffers();//因为使用的是双缓存GLUT_DOUBLE,所以这里必须要交换缓存才会显示
}
} #endif //处理鼠标点击
void Mouse(int button, int state, int x, int y)
{
if(state == GLUT_DOWN) //第一次鼠标按下时,记录鼠标在窗口中的初始坐标
{
//记住鼠标点击后光标坐标
cx = x;
cy = y;
//printf("Mouse: x=%d, y=%d, oldx=%f, oldy=%f\n", x, y, oldx, oldy);
}
} //处理鼠标拖动
void onMouseMove(int x, int y)
{
int offset = ;
if (cx <= && y < cy) {//左半边区:顺时针手势
angle -= offset;
printf("angle1=%d\n", angle);
} else if (cx > && y > cy) {//右半边区:顺时针手势
angle -= offset;
printf("angle2=%d\n", angle);
} else if (cx <= && y > cy) {//左半边区:逆时针手势
angle += offset;
printf("angle3=%d\n", angle);
} else if (cx > && y < cy) {//右半边区:逆时针手势
angle += offset;
printf("angle4=%d\n", angle);
}
angle %= ; //计算拖动后的偏移量,然后进行xy叠加减
oldx += ((x - cx) * 0.01);
oldy -= ((y - cy) * 0.01);
//printf("Move: x=%d(%d)[%d], y=%d(%d)[%d], oldx=%f, oldy=%f\n", x, cx, x-cx, y, cy, y-cy, oldx, oldy);
glutPostRedisplay(); //保存好当前拖放后光标坐标点
cx = x;
cy = y;
} void reshape(int w, int h)
{
int offset = ;
int dis = (w > h ? h : w) - offset * ; //配置显示物体屏幕的大小
glViewport(offset, offset, (GLsizei)dis, (GLsizei)dis);
printf("reshape: w=%d, h=%d, dis=%d\n", w, h, dis); glMatrixMode(GL_PROJECTION);
glLoadIdentity(); //glOrtho(-1.5, 1.5, -1.5, 1.5, 0, 100);
//gluOrtho2D(-1.5, 1.5, -1.5, 1.5);
gluPerspective(90.0f, (GLfloat)w/(GLfloat)h, 0.1f, 100.0f); glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
} int main(int argc, char *argv[])
{
glutInit(&argc, argv); glutInitDisplayMode(GLUT_RGB | (OUTPUT_MODE == ? GLUT_SINGLE : GLUT_DOUBLE));
glutInitWindowPosition(, );
glutInitWindowSize(, );
glutCreateWindow("第一个 OpenGL 程序"); init();
glutDisplayFunc(&display);
glutIdleFunc(display); //设置不断调用显示函数
glutReshapeFunc(reshape);
glutMouseFunc(Mouse);
glutMotionFunc(onMouseMove);
glutMainLoop();
return ;
}

没有录制,附上几张图

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

OpenGL的几何变换2之内观察立方体的更多相关文章

  1. OpenGL的几何变换3之内观察全景图

    继续上一篇文章的例子:OpenGL的几何变换2之内观察立方体 上一篇是通过绘图方式得到的立方体,没有贴图,这次加上纹理贴图. 通过纹理贴图有两种方案: 1.图片分割化,即是把一张完整的全景图片(就是支 ...

  2. OpenGL的几何变换4之内观察全景图

    上一次写了OpenGL的几何变换3之内观察全景图 上次采用的是图片分割化方式,这次采用数据分割化方式. 先说下思路,数据分割化方式呢,是只读取一张图片imgData,然后通过glTexCoord2f( ...

  3. OpenGL的几何变换[转]

    OpenGL的几何变换 1.实验目的: 理解掌握一个OpenGL程序平移.旋转.缩放变换的方法. 2.实验内容: (1)阅读实验原理,运行示范实验代码,掌握OpenGL程序平移.旋转.缩放变换的方法: ...

  4. OpenGL的glViewPort窗口设置函数实现分屏

    之前实现过全景图片查看(OpenGL的几何变换3之内观察全景图),那么我们需要进行分屏该如何实现呢?如下图: 没错就是以前提过的glViewPort函数,废话不多说了,我直接上代码: //从这里开始进 ...

  5. NeHe OpenGL教程 第五课:3D空间

    转自[翻译]NeHe OpenGL 教程 前言 声明,此 NeHe OpenGL教程系列文章由51博客yarin翻译(2010-08-19),本博客为转载并稍加整理与修改.对NeHe的OpenGL管线 ...

  6. OpenGL学习进程(9)在3D空间的绘制实例

        本节将演示在3D空间中绘制图形的几个简单实例:     (1)在3D空间内绘制圆锥体: #include <GL/glut.h> #include <math.h> # ...

  7. opengl绘制三维人物luweiqi

    素材中有四个.bmp格式的纹理文件和一个.txt的模型参数文件 文件格式说明: 纹理文件数量 纹理文件1(字符串)//.bmp 纹理文件2(字符串) 纹理文件3(字符串) . . . 材质数量 amb ...

  8. 第05课 OpenGL 3D空间

    3D空间: 我们使用多边形和四边形创建3D物体,在这一课里,我们把三角形变为立体的金子塔形状,把四边形变为立方体. 在上节课的内容上作些扩展,我们现在开始生成真正的3D对象,而不是象前两节课中那样3D ...

  9. OpenGL的gluPerspective和gluLookAt的关系[转]

    函数原型void gluLookAt(GLdoble eyex, GLdouble eyey, GLdouble eyez,  GLdouble centerx, GLdouble centery, ...

随机推荐

  1. U3D刚体测试1-刚体非刚体物体非Kinematic等之间的碰撞关系

    Unity官方有一个详细的碰撞关系表:http://docs.unity3d.com/Manual/CollidersOverview.html 但其实可以精简为以下几点: 1.两个勾选kinemat ...

  2. 2007 Asia - Nanjing F题,字典树

    题目链接:https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&category=2 ...

  3. linux之eventfd()

    参考:http://www.man7.org/linux/man-pages/man2/eventfd.2.html 一.简介 简单来说,这个函数就是创建一个用于事件通知的文件描述符.它类似于pipe ...

  4. web简单连接html文件测试

    Web工程: 条件: apache-tomcat-6.0.20(文件夹/7.0)=======位于E盘 标题:链接服务器 步骤: 第一步:打开apache-tomcat-6.0.20-bin-star ...

  5. 干净的卸载Oracle

    一.在oracle11G以前卸载oracle会存在卸载不干净,导致再次安装失败的情况,在运行services.msc打开服务,停止Oracle的所有服务. 二. oracle11G自带一个卸载批处理\ ...

  6. JS结构图

  7. C# for和 foreach 的数组遍历 比较

    刚学习程序,感觉写代码 很有意思,所以把自己的感悟写下来啦,第一次写博客,可能是菜鸟中的菜鸟  时间久了,相信就会写的很好哦! for和 foreach 的数组遍历 比较 很简单的程序,不解释啦! u ...

  8. SpringMVC拦截器2(资源和权限管理)(作为补充说明)

    SpringMVC拦截器(资源和权限管理) 1.DispatcherServlet SpringMVC具有统一的入口DispatcherServlet,所有的请求都通过DispatcherServle ...

  9. Python3基础 print 中字符串乘以数字,重复输出多次

    镇场诗:---大梦谁觉,水月中建博客.百千磨难,才知世事无常.---今持佛语,技术无量愿学.愿尽所学,铸一良心博客.------------------------------------------ ...

  10. 协方差Covariance的表述推导

    今天想了一下关于概率论的一维数据期望.方差以及高维数据的矩阵表示,突然想到为什么在一维中 方差的表示为:V(x) = E((x-E(x))2) 而到了高维,这样的表述就成了协方差呢?V(X) = E( ...