OpenGL的几何变换2之内观察立方体
我想实现的一个场景是:一个立方体,相机的坐标在立方体的中心点,相机不变,立方体旋转,可以站在立方体中心点查看立方体内部。
实际上就是立方体图像,这是在全景图片当作比较简单的方式,画面不会变形和扭曲,但是现在拍摄的全景图不会这样拍摄,更多的可点击先搞清楚全景视频是如何实现的查看
其实就是当下炒得火热的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之内观察立方体的更多相关文章
- OpenGL的几何变换3之内观察全景图
继续上一篇文章的例子:OpenGL的几何变换2之内观察立方体 上一篇是通过绘图方式得到的立方体,没有贴图,这次加上纹理贴图. 通过纹理贴图有两种方案: 1.图片分割化,即是把一张完整的全景图片(就是支 ...
- OpenGL的几何变换4之内观察全景图
上一次写了OpenGL的几何变换3之内观察全景图 上次采用的是图片分割化方式,这次采用数据分割化方式. 先说下思路,数据分割化方式呢,是只读取一张图片imgData,然后通过glTexCoord2f( ...
- OpenGL的几何变换[转]
OpenGL的几何变换 1.实验目的: 理解掌握一个OpenGL程序平移.旋转.缩放变换的方法. 2.实验内容: (1)阅读实验原理,运行示范实验代码,掌握OpenGL程序平移.旋转.缩放变换的方法: ...
- OpenGL的glViewPort窗口设置函数实现分屏
之前实现过全景图片查看(OpenGL的几何变换3之内观察全景图),那么我们需要进行分屏该如何实现呢?如下图: 没错就是以前提过的glViewPort函数,废话不多说了,我直接上代码: //从这里开始进 ...
- NeHe OpenGL教程 第五课:3D空间
转自[翻译]NeHe OpenGL 教程 前言 声明,此 NeHe OpenGL教程系列文章由51博客yarin翻译(2010-08-19),本博客为转载并稍加整理与修改.对NeHe的OpenGL管线 ...
- OpenGL学习进程(9)在3D空间的绘制实例
本节将演示在3D空间中绘制图形的几个简单实例: (1)在3D空间内绘制圆锥体: #include <GL/glut.h> #include <math.h> # ...
- opengl绘制三维人物luweiqi
素材中有四个.bmp格式的纹理文件和一个.txt的模型参数文件 文件格式说明: 纹理文件数量 纹理文件1(字符串)//.bmp 纹理文件2(字符串) 纹理文件3(字符串) . . . 材质数量 amb ...
- 第05课 OpenGL 3D空间
3D空间: 我们使用多边形和四边形创建3D物体,在这一课里,我们把三角形变为立体的金子塔形状,把四边形变为立方体. 在上节课的内容上作些扩展,我们现在开始生成真正的3D对象,而不是象前两节课中那样3D ...
- OpenGL的gluPerspective和gluLookAt的关系[转]
函数原型void gluLookAt(GLdoble eyex, GLdouble eyey, GLdouble eyez, GLdouble centerx, GLdouble centery, ...
随机推荐
- java 四舍五入 保留俩位小数
public static void main(String[] args) { String str="0"; BigDeci ...
- 20151124001 关闭C#主窗体弹出是否关闭对话框
关闭C#主窗体弹出是否关闭对话框 private void Frm_Main_FormClosing(object sender, FormClosingEventArgs e) { ...
- 移动端web出现的一系列问题
今天做移动端的web,在做后期处理的时候,发现了非常多的问题.下面我分别列举一下吧~~ 1.移动端浏览器众多,各种浏览器之间的显示等都有差异,很多需要单独处理,于是我需要判断分别是什么浏览器.js代码 ...
- Animation在每一帧中的执行顺序测试
测试代码: void Update() { transform.position = Vector3.zero; } void LateUpdate() { Debug.Log(transform.p ...
- Mac环境下用Java(Sikuli+Robot)实现页游自动化
转载请注明出自天外归云的博客园:http://www.cnblogs.com/LanTianYou/ Sikulix(以前叫Sikuli)在Mac电脑的环境配置步骤如下: 1.从官网上下载Sikuli ...
- common-pool2 使用
common-pool2提供了3中对象池管理方式,它们的使用方式基本一样,这里以GenericObjectPool对象池为例介绍其使用方式,一般实现自己的对象池需要经过2个步骤 1.实现PooledO ...
- 如何用Pr完成作业~
要求~ 我的工具~(随便搞搞就好了,自己的录音还没弄~)
- 修改Netbeans默认使用UTF-8编码
NetBeans是一款优秀的开源集成开发环境,可以用于Java,C/C++,PHP等语言的开发.同时它也是一个可扩展的开发平台,可以通过插件来扩展官方版本没有的功能.自从被Oracle这个开源杀手收购 ...
- mysql DATE_ADD DATE_SUB
一.DATE_ADD() 函数向日期添加指定的时间间隔. DATE_ADD(date,INTERVAL expr type)date 参数是合法的日期表达式.expr 参数是您希望添加的时间间隔. t ...
- Python3基础 大于一个数的同时小于一个数
镇场诗:---大梦谁觉,水月中建博客.百千磨难,才知世事无常.---今持佛语,技术无量愿学.愿尽所学,铸一良心博客.------------------------------------------ ...