原博主博客地址:http://blog.csdn.net/qq21497936
本文章博客地址:http://blog.csdn.net/qq21497936/article/details/78660326
《OpenGL学习笔记》系列博客目录地址:http://blog.csdn.net/qq21497936/article/category/7315532
经常看到技术需求当中有opengl,所以有时间就介绍并学习下opengl,opengl对于qt来说只是窗口不一样,其调用的实际函数都是opengl的原生函数,所以这可以说学会opengl是完全意义上的一通百通。
在OpenGL里面移动坐标是相对于当前点开始移动的相对坐标;
在OpenGL里面绕轴变换,每次画图形之前会设置一个变换原点,变换的轴必须通过该点,所以要实现理想的变换,必须很好的掌握此相对于变换图形的“原点”(非整体坐标系原点)。
创建完成后,首先就是要该窗口继承的基类QWidget改为QGLWidget。
在工程文件.pro加入:
QT += opengl
头文件加入,特别注意包含GL/glu,否则调用glu函数会没有
#include
#include // 必须包含,否则glu相关函数无法使用
重载三个函数
protected:
void initializeGL(); // 用来初始化
void paintGL(); // 用来绘制,更新发生,就会被调用
void resizeGL(int width, int height); // 窗口大小变化时,会调用
至此Qt OpenGL基本的程序窗口搭建完毕,不论任何语言的opengl的使用,除了之前创建窗口不同之外,以下opengl学习调用的函数为opengl的原生函数。
初始化窗口代码
void NeHeWidget::initializeGL() // 每次paintgGL()或resizeGL()之前会自动调用
{
// 启用smooth shading(阴影平滑)
glShadeModel(GL_SMOOTH);
// 设置清楚屏幕所用的颜色 色彩值范1围从0.0-1.0 (R G B A) 清屏时A不起作用
glClearColor(0.1, 0.1, 0.4, 1.0);
/* 以下三行必须做,是关于深度缓存的,深度缓存是OpenGL十分重要的部分*/
// 设置深度缓存
glClearDepth(1.0);
// 启用深度测试
glEnable(GL_DEPTH_TEST);
// 设置深度测试的类型
glDepthFunc(GL_LEQUAL);
// 设置希望得到最好的透视修正
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
}
画一个三角形和一个四边形,填充颜色,并让三角形饶Y轴变换,四边形绕X轴变换
void NeHeWidget::paintGL()
{
// 清除屏幕和深度缓存
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// 重置观察矩阵/投影矩阵
// (X坐标轴从左至右,Y坐标轴从下至上,Z坐标轴从里至外)
// OpenGL屏幕中心的坐标值是X和Y轴上的0.0点
// 中心左面的坐标值是负值,右面是正值。
// 移向屏幕顶端是正值,移向屏幕底端是负值。
// 移入屏幕深处是负值,移出屏幕则是正值。
glLoadIdentity();
// 沿着X、Y、Z轴移动
// X轴左移1.5个单位,Y轴不动(0.0),最后移入屏幕6.0个单位
// 注意在glTranslatef(x, y, z)中当您移动的时候,
// 您并不是相对屏幕中心移动,而是相对与当前所在的屏幕位置
glTranslatef(-1.5, 0.0, -6.0);
// 让对象绕某个轴旋转 绕 Y 轴旋转三角形
glRotatef(rTri, 0.0, 1.0, 0.0); 注意:X轴旋转,X,Y,Z可调整绕哪个轴
// glBegin(GL_TRIANGLES)开始绘制三角
// 以目前所在的点为画图原点(0,0,0) 开始相对原点坐标画三角形
glBegin(GL_TRIANGLES);
glColor3f( 1.0, 0.0, 0.0 ); // 红色 颜色+顶点
glVertex3f( 0.0, 1.0, 0.0); // 中上顶点 红色+中上
glColor3f( 0.0, 1.0, 0.0 ); // 绿色
glVertex3f(-1.0, -1.0, 0.0 ); // 左下顶点 绿色+左下
glColor3f( 0.0, 0.0, 1.0 ); // 蓝色
glVertex3f( 1.0, -1.0, 0.0 ); // 右下顶点 蓝色+右下
// glEnd()告诉OpenGL图形(三角)已经创建好了 // 三点间自动使用渐变填充
glEnd();
// 重置模型观察矩阵 重置模型观察矩阵之后,X、Y、Z轴都以复位
glLoadIdentity();
glTranslatef( 1.5, 0.0, -6.0 ); // 移动到点
// 绕 X 轴旋转四边形 注意:X轴旋转,X,Y,Z可调整绕哪个轴
glRotatef(rQuad, 1.0, 0.0, 0.0);
// 绘制四边形
// 以目前所在的点为画图原点(0,0,0) 开始相对原点坐标画四边形
glBegin( GL_QUADS );
glColor3f( 0.5, 0.5, 1.0 ); // 蓝色,下面画的点都是蓝色直到换颜色后换点
glVertex3f(-1.0, 1.0, 0.0 ); // 左上顶点
glVertex3f( 1.0, 1.0, 0.0 ); // 右上定点
glVertex3f( 1.0, -1.0, 0.0 ); // 右下定点
glVertex3f(-1.0, -1.0, 0.0 ); // 坐下定点
glEnd();
}
每当窗口做大小改变的时候,我们需要resizeGL整个窗口大小
void NeHeWidget::resizeGL(int width, int height)
{
// 防止height为0
if(height == 0)
{
height = 1;
}
// 重置当前的视口
glViewport(0, 0, (GLint)width, (GLint)height);
// 选择投影矩阵
glMatrixMode(GL_PROJECTION);
// 重置观察矩阵/投影矩阵 当调用次函数,实际将当前点移到了屏幕中心
glLoadIdentity();
// 建立透视投影矩阵,需要头文件
gluPerspective( 45.0, (GLfloat)width/(GLfloat)height, 0.1, 100.0 );
// 选择模型观察矩阵
glMatrixMode( GL_MODELVIEW );
// 重置观察矩阵/投影矩阵
glLoadIdentity();
}
最后我们需要不断的定时修改旋转角度,修改后需要刷新,定义定时器
_pTimer = new QTimer(this);
_pTimer->setInterval(10);
connect(_pTimer, SIGNAL(timeout()), this, SLOT(slotRotate()));
_pTimer->start();
定时器函数,可使用startTimer函数来使用窗口自带的timerEvent定时事件
void NeHeWidget::slotRotate()
{
rTri+=1; // 增加三脚形Y轴角度
rQuad+=1; // 增加四边形X轴角度
update(); // 刷新
}
使三角形绕非标准轴运动
…
// 绕 X 轴旋转四边形
glRotatef(rQuad, 1.0, 0.0, 0.0);
…
修改后
// 使其绕XZ平面45°轴运动,该轴通过该图形初始化原点…
…
glRotatef(rQuad, 1.0, 0.0, 1.0);
…
关于图形初始化原点,是开始画图形之前设置的相对原点,以此点为0,0,0为坐标开始画图形,具体代码如下,glTranslatef后的glBegin和glEnd之间所花的图形,其旋转变换轴必须通过glTranslatef的相对原点
// 清除屏幕和深度缓存
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// 重置观察矩阵/投影矩阵
// (X坐标轴从左至右,Y坐标轴从下至上,Z坐标轴从里至外)
// OpenGL屏幕中心的坐标值是X和Y轴上的0.0点
// 中心左面的坐标值是负值,右面是正值。
// 移向屏幕顶端是正值,移向屏幕底端是负值。
// 移入屏幕深处是负值,移出屏幕则是正值。
glLoadIdentity();glLoadIdentity();
// 沿着X、Y、Z轴移动
// X轴左移1.5个单位,Y轴不动(0.0),最后移入屏幕6.0个单位
// 注意在glTranslatef(x, y, z)中当您移动的时候,
// 您并不是相对屏幕中心移动,而是相对与当前所在的屏幕位置
glTranslatef(-1.5, 0.0, -6.0);
// 让对象绕某个轴旋转 绕 Y 轴旋转三角形
glRotatef(rTri, 1.0, 1.0, 0.0);
// glBegin(GL_TRIANGLES)开始绘制三角
// 以目前所在的点为画图原点(0,0,0) 开始相对原点坐标画三角形
glBegin(GL_TRIANGLES);
glColor3f( 1.0, 0.0, 0.0 ); // 红色 // 颜色+顶点
glVertex3f( 0.0, 1.0, 0.0); // 中上顶点 红色+中上
glColor3f( 0.0, 1.0, 0.0 ); // 绿色
glVertex3f(-1.0, -1.0, 0.0 ); // 左下顶点 绿色+左下
glColor3f( 0.0, 0.0, 1.0 ); // 蓝色
glVertex3f( 1.0, -1.0, 0.0 ); // 右下顶点 蓝色+右下
// glEnd()告诉OpenGL图形(三角)已经创建好了 // 三点间自动使用渐变填充
glEnd();
使三角形绕非标准轴运动
…
//使其绕XY平面45°轴运动,该轴通过该图形初始化原点
glTranslatef( 1.5, 0.0, -6.0 ); // 移动到点
// 绕 X 轴旋转四边形
glRotatef(rQuad, 1.0, 1.0, 0.0);
…
修改后
…
//使其绕XZ平面45°轴运动,该轴通过该图形初始化原点
glTranslatef( 1.5, 0.0, -6.0 ); // 移动到点
// 绕 X 轴旋转四边形
glRotatef(rQuad, 1.0, 0.0, 0.0);
…
原博主博客地址:http://blog.csdn.net/qq21497936
本文章博客地址:http://blog.csdn.net/qq21497936/article/details/78660326