OpenGL_Qt学习笔记之_03(平面图形的着色和旋转)(转)
http://www.cnblogs.com/tornadomeet/archive/2012/08/23/2653305.html
在这一节中主要简单介绍下怎样给平面几何着色,以及怎样让绘制出来的几何图形旋转起来。在上一节OpenGL_Qt学习笔记之_02(绘制简单平面几何图形) 中已经介绍了如何利用opengl画一些简单的图像,那么这一节就在上面的基础上给它着色,且让他旋转。
实验基础
首先来看着色,其实着色在上篇文章中已经用过,使用的是函数glColor3f()。一旦我们使用这个函数着色后且不更改颜色,则后面所绘的图形都是这个颜色了。我们给多边形着色时,表面上看都是给它的顶点着色,其实因为我们在initializeGL()函数中已经设置过glShapeModel(GL_SMOOTH),即颜色阴影是平滑模式。所以当我们给顶点设置后颜色后,其所构成的多边形内部就会按照一定规律自动填充颜色,且是平滑过渡。
下面来看看旋转,首先是要了解opengl的一个三维空间,如下图所示:

如果是按照X轴旋转的话,就是图中的指向视点那个轴了,NeHe教程中把沿x轴旋转比作成一台台钜,锯片中心的轴从左至右摆放,尖利的锯齿绕着X轴狂转,看起来要么向上转,要么向下转。把Y轴旋转比喻成巨大的龙卷风过程,龙卷风的中心从地面指向天空,垃圾和碎片围着Y轴从左向右或是从右向左狂转不止。把z轴旋转比喻成从正前方看着一台工作着的风扇。风扇的叶片绕着Z轴顺时针或逆时针狂转。这个比喻很形象。
其实大家凭想象都能想出来是怎么转的,这里不再罗嗦了。Opengl中关于旋转使用的是函数:
glRotatef( Angle, Xvector, Yvector, Zvector )
Angle 通常是个变量代表对象转过的角度。 Xvector , Yvector 和 Zvector 三个参数则共同决定旋转轴的方向。比如(1,0,0)所描述的矢量经过X坐标轴的1个单位处并且方向向右。(-1,0,0)所描述的矢量经过X坐标轴的1个单位处,但方向向左。
实验说明
我在给圆着色时,每次给一个顶点赋值一种颜色,因为画圆是用三角形来逼近的,所以有很多顶点,且我这里给的顶点的颜色是随机赋值的,随机函数用的是Qt中自带的qrand(),
qrand()%10表示产生0~9之间的整数,因此(GLfloat)(qrand()%10)/10则表示0.0~0.9之间的小数。
在我这次试验中同样要注意,因为屏幕大小本身就2个单位的长和宽,所以设置旋转的轴时取值要适当,否则很难观察到旋转的效果。
实验结果
着色结果:

旋转时截取的一张图效果:

旋转的时候为了看到效果,可以不断改变窗口的大小,让GLWidget这个类不断执行paintGL()函数,实现重绘来看旋转效果。
实验主要部分代码及解释(附录有工程code下载链接地址)。
glwidget.cpp:

#include "glwidget.h"
#include "ui_glwidget.h" #include <QtGui>
#include <QtCore>
#include <QtOpenGL> #define GL_PI 3.1415926
#define GL_RADIUX 0.2f GLWidget::GLWidget(QGLWidget *parent) :
QGLWidget(parent),
ui(new Ui::GLWidget)
{
// setWindowTitle("The Opengl for Qt Framework");
ui->setupUi(this);
fullscreen = false;
triangle_rotate = 0.0;
quads_rotate = 0.0;
circle_rotate = 0.0;
} //这是对虚函数,这里是重写该函数
void GLWidget::initializeGL()
{
setGeometry(300, 150, 500, 500);//设置窗口初始位置和大小
glShadeModel(GL_SMOOTH);//设置阴影平滑模式
glClearColor(0.0, 0.0, 0.0, 0.0);//改变窗口的背景颜色,不过我这里貌似设置后并没有什么效果
glClearDepth(1.0);//设置深度缓存
glEnable(GL_DEPTH_TEST);//允许深度测试
glDepthFunc(GL_LEQUAL);//设置深度测试类型
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);//进行透视校正
} void GLWidget::paintGL()
{ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //glClear()函数在这里就是对initializeGL()函数
//中设置的颜色和缓存深度等起作用
glLoadIdentity();//重置当前的模型观察矩阵,该句执行完后,将焦点移动到了屏幕的中心 /*下面几句代码是用来画三角形的,以glBegin()开始,glEnd()结束;glVertex3f为给定一个3维的顶点,坐标值为浮点型*/
glTranslatef(-0.3, 0.3, -0.6);
glRotatef(triangle_rotate, 0.2, 0.2, 0.0);//设置旋转的角度,这里为了观察,同时沿x轴和y轴做了旋转
glBegin(GL_TRIANGLES);//GL_TRIANGLES代表为画三角形
glVertex3f(0.0f, 0.2f, 0.0f);//上顶点坐标
glColor3f(1.0f, 0.0f, 0.0f);
glVertex3f(-0.2f, -0.2f, 0.0f);//左下角坐标
glColor3f(0.0f, 1.0f, 0.0f);
glVertex3f(0.2f, -0.2f, 0.0f);//右下角坐标
glColor3f(0.0f, 0.0f, 1.0f);
glEnd();//结束画完
triangle_rotate += 0.05; //为了看到动态效果,这里每次刷新后旋转的角度都加0.05 glLoadIdentity();//重新焦点定位,同样是屏幕的中心
glTranslatef(0.3f,0.3f,0.0f); // 向x轴正方向移动0.3个单位
glRotatef(quads_rotate, 0.0, 0.2, 0.2);
glColor3f(0.0f,1.0f,0.0f);//颜色设置放在这个地方,对下面的顶点设置都是有效的 /*下面开始绘制四边形*/
glBegin(GL_QUADS);
glVertex3f(-0.2f, 0.2f, 0.0f); // 左上顶点
glColor3f(1.0f, 0.0f, 0.0f);
glVertex3f( 0.2f, 0.2f, 0.0f); // 右上顶点
glColor3f(0.0f, 1.0f, 0.0f);
glVertex3f( 0.2f, -0.2f, 0.0f); // 右下顶点
glColor3f(0.0f, 0.0f, 1.0f);
glVertex3f(-0.2f, -0.2f, 0.0f); // 左下顶点
glColor3f(1.0f, 0.2f, 0.8f);
glEnd(); // 四边形绘制结束
quads_rotate += 0.05; glLoadIdentity();
glTranslatef(0.0f, -0.3f, 0.0f);
glColor3f(0.0f, 0.0f, 1.0f);
glRotatef(circle_rotate, 0.2, 0.0, 0.2); /*这里用连续的三角形面积来逼近圆的面积实现圆周的画法*/
GLint circle_points = 100, i = 0;
glBegin(GL_TRIANGLE_FAN);
for(int i = 0; i < circle_points; i++ )
{
double angle = 2*GL_PI*i/circle_points;
//qrand()%10为产生0~10的整数,这里的颜色是随机产生的
glColor3f((GLfloat)(qrand()%10)/10, (GLfloat)(qrand()%10)/10, (GLfloat)(qrand()%10)/10);
glVertex3f(GL_RADIUX*cos(angle), GL_RADIUX*sin(angle), 0);
}
glEnd();
circle_rotate += 0.05; } //该程序是设置opengl场景透视图,程序中至少被执行一次(程序启动时).
void GLWidget::resizeGL(int width, int height)
{
if(0 == height)
height = 1;//防止一条边为0
glViewport(0, 0, (GLint)width, (GLint)height);//重置当前视口,本身不是重置窗口的,只不过是这里被Qt给封装好了
glMatrixMode(GL_PROJECTION);//选择投影矩阵
glLoadIdentity();//重置选择好的投影矩阵
// gluPerspective(45.0, (GLfloat)width/(GLfloat)height, 0.1, 100.0);//建立透视投影矩阵
glMatrixMode(GL_MODELVIEW);
glLoadIdentity(); }
void GLWidget::keyPressEvent(QKeyEvent *e)
{
switch(e->key())
{
//F1键为全屏和普通屏显示切换键
case Qt::Key_F1:
fullscreen = !fullscreen;
if(fullscreen)
showFullScreen();
else
{
setGeometry(300, 150, 500, 500);
showNormal();
}
updateGL();
break;
//Ese为退出程序键
case Qt::Key_Escape:
close();
}
} GLWidget::~GLWidget()
{
delete ui;
}

总结:opengl中实现平面图形的着色和旋转,实现起来比较简单,只需要对对应的函数赋即可。
参考资料:
http://www.owlei.com/DancingWind/
http://blog.csdn.net/qp120291570/article/details/7853513
附录:
OpenGL_Qt学习笔记之_03(平面图形的着色和旋转)(转)的更多相关文章
- OpenGL_Qt学习笔记之_05(纹理映射)(转)
转自:http://www.cnblogs.com/tornadomeet/archive/2012/08/24/2654719.html 纹理映射基础知识 什么叫纹理映射,一开始我也不明白,感觉这个 ...
- OpenGL ES学习笔记(二)——平滑着色、自适应宽高及三维图像生成
首先申明下,本文为笔者学习<OpenGL ES应用开发实践指南(Android卷)>的笔记,涉及的代码均出自原书,如有需要,请到原书指定源码地址下载. <Android学习笔记--O ...
- Directx11学习笔记【十二】 画一个旋转的彩色立方体
上一次我们学习了如何画一个2D三角形,现在让我们进一步学习如何画一个旋转的彩色立方体吧. 具体流程同画三角形类似,因此不再给出完整代码了,不同的部分会再说明. 由于我们要画彩色的立方体,所以顶点结构体 ...
- OpenGL ES学习笔记(三)——纹理
首先申明下,本文为笔者学习<OpenGL ES应用开发实践指南(Android卷)>的笔记,涉及的代码均出自原书,如有需要,请到原书指定源码地址下载. <OpenGL ES学习笔记( ...
- 左偏树 / 非旋转treap学习笔记
背景 非旋转treap真的好久没有用过了... 左偏树由于之前学的时候没有写学习笔记, 学得也并不牢固. 所以打算写这么一篇学习笔记, 讲讲左偏树和非旋转treap. 左偏树 定义 左偏树(Lefti ...
- matlab学习笔记9 高级绘图命令_2 图形的高级控制_视点控制和图形旋转_色图和颜色映像_光照和着色
一起来学matlab-matlab学习笔记9 高级绘图命令_2 图形的高级控制_视点控制和图形旋转_色图和颜色映像_光照和着色 觉得有用的话,欢迎一起讨论相互学习~Follow Me 参考书籍 < ...
- Introduction to 3D Game Programming with DirectX 12 学习笔记之 --- 第十三章:计算着色器(The Compute Shader)
原文:Introduction to 3D Game Programming with DirectX 12 学习笔记之 --- 第十三章:计算着色器(The Compute Shader) 代码工程 ...
- Introduction to 3D Game Programming with DirectX 12 学习笔记之 --- 第十二章:几何着色器(The Geometry Shader)
原文:Introduction to 3D Game Programming with DirectX 12 学习笔记之 --- 第十二章:几何着色器(The Geometry Shader) 代码工 ...
- 离屏渲染学习笔记 /iOS圆角性能问题
离屏渲染学习笔记 一.概念理解 OpenGL中,GPU屏幕渲染有以下两种方式: On-Screen Rendering 意为当前屏幕渲染,指的是GPU的渲染操作是在当前用于显示的屏幕缓冲区中进行. O ...
随机推荐
- 2015年第六届蓝桥杯C/C++程序设计本科B组决赛 完美正方形
完美正方形 如果一些边长互不相同的正方形,可以恰好拼出一个更大的正方形,则称其为完美正方形.历史上,人们花了很久才找到了若干完美正方形.比如:如下边长的22个正方形 2 3 4 6 7 8 12 13 ...
- 第一次项目上Linux服务器(三:安装Tomcat及相关命令)
一.下载Tomcat 去官网:http://tomcat.apache.org/ 找到要下载的Tomcat 本人下载的是apache-tomcat-8.5.29.tar.gz,百度云资源链接:链接:h ...
- Windows服务设置
[服务列表]services.msc [注册服务] 描述:在注册表和服务数据库中创建服务项. 用法:sc <server> create [service name] [binPath= ...
- VC++窗口创建过程,图形绘制,时钟程序
创建窗口步骤: (1)注册窗口类(RegisterClassEx) (2)创建窗口(CreateWindowEx) (3)在桌面显示窗口(ShowWindow) (4)更新窗口客户区(UpdateWi ...
- WIN7 下IIS7的rewrite伪静态功能设置方法
win7系统都自带有iis的功能.关于WIN7下IIS的安装,请参考这里 http://jingyan.baidu.com/article/219f4bf723bcb2de442d38ed.html ...
- 【ibatis】IBatis介绍
Ⅰ .什么是Ibatis? ① iBATIS的是一个持久层框架,它能够自动在 Java, .NET, 和Ruby on Rails中与SQL数据库和对象之间的映射.映射是从应用程序逻辑封装在XML配置 ...
- angularjs 2.0 简单入门1
一:首先要写json文件,并下载所有的包 1,在任意目录下新建文件夹 命名为angular2Dome,也可以使用命令 mkdir angular2Dome 回车. 2,在angular2Dome文件 ...
- JAVA设计模式详解(五)----------适配器模式
各位朋友好,本章节我们继续讲第五个设计模式. 在生活中,我们都知道手机内存卡是无法直接接电脑的,因为内存卡的卡槽比较小,而电脑只有USB插孔,此时我们需要用到读卡器.这个读卡器就相当于是适配器.这是生 ...
- SpringBoot启动加载类ApplicationRunner
SpringBoot启动加载类ApplicationRunner 有时希望项目在启动的时候加载一些系统参数,就要用到ApplicationRunner ApplicationRunner是一个接口,我 ...
- Spring Data Solr —— 快速入门
Solr是基于Lucene(全文检索引擎)开发,它是一个独立系统,运行在Tomcat或Jetty(solr6以上集成了jetty,无需再部署到servlet容器上),但其原生中文的分词词功能不行,需要 ...