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

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

其实就是当下炒得火热的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. hdu 3398

    String Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Subm ...

  2. java 抽象类和接口的区别

    抽象类 特点: 1.抽象类中可以构造方法 2.抽象类中可以存在普通属性,方法,静态属性和方法. 3.抽象类中可以存在抽象方法. 4.如果一个类中有一个抽象方法,那么当前类一定是抽象类:抽象类中不一定有 ...

  3. Java动态代理 cglib

    代理模式:为某些对象提供代理以实现对这个对象的访问. 对一个对象进行访问控制的原因是为了只有在我们确实需要这个对象时才对它进行创建和初始化. 一般包括以下组件: 被代理者接口:提供被代理者的访问途径. ...

  4. 第六课 SQLite

    总结:SQLite 1.SQLite的数据类型: NULL(空值).INTEGER(整型值).READL(浮点值).TEXT(字符串值).BLOB(二进制对象); 2.SQLite的应用 2.1 SQ ...

  5. Centos 中如何快速定制二进制的内核RPM 包

    随着Linux服务器越来越多了,底层系统内核想要保持版本统一就需要定制专门的二进制安装包来便捷的升级和管理. RedHat系那当然就是使用rpmbuild来做定制化管理了. 今天我们分俩个部分(roo ...

  6. CentOS 6.5中linux grub修复

    在使用Linux的过程中,难免会出现开机提示grub >而无法启动,可能是系统中/boot/grub文件丢失等原因造成的,当出现此问题的时候只要系统分区没有格式化一般是可以修复的,下面就以虚拟 ...

  7. JAVA_输入输出流 异常处理

    输入输出流 文件创建

  8. python处理字符串时出现的错误'ascii' codec can't decode byte 0xe9 in position 0: ordinal not in range(128)" 解决方法

    解决办法,在该python文件的前面加上如下几句,问题得到解决. import sys default_encoding = 'utf-8' if sys.getdefaultencoding() ! ...

  9. deep-learning-frameworks

    From: http://venturebeat.com/2015/11/14/deep-learning-frameworks/ Here’s a rundown of some other not ...

  10. 【转】在网页中运行VB6程序

      用VB6做的程序在网页里运行, 需要把程序做成OCX格式,下面简单做一介绍: 首先新建一个工程, 选择ActivX控件: 然后添加控件和代码: 然后F5运行 然后按下图设置,去掉弹出消息阻止 这样 ...