学习OpenGL也有段时间了,前几篇将GL最基本的画图过程解析了一下,后面进阶的就随项目需要再学。因为之前一直是用glut这个实用工具包来开发很方便,但是会附带一个控制台的窗口,实在觉得有些low,因此就打算将GL嵌入到应用程序中去。

  下面就把前几章学习的知识结合起来,在QT下实现GL的动画。之所以选QT而非MFC原因有2点,一则是QT是开源的,现在开源的东西都很热闹,所以我也凑凑热闹,之前用MFC做过别的上位机程序,我是个喜欢图新鲜的人;二则QT的移植性好,一次编译到处运行吧。

  总结几处注意点:

  1.glut的函数是一个也不能使用了,需要自己用QT的Widget类来创建应用窗口,同时再用QGLWidget类创建自己的GL类,将二者绑定在一起;

  2.需要重载QGLWidget的三个重要函数initializeGL、resizeGL和paintGL;

  3.glClear函数不属于initializeGL,即即使你写入它,在初始化的时候也不会被执行;

  4.需要显示裁剪视口以及设定透视方法,这些在之前使用glut中函数的时候会被默认设置和创建窗口匹配。什么意思呢?就是如果不显示设定的话,你会被坐标定位搞得糊里糊涂。这个也是我第一次移植时候遇到的困扰,其实程序是正常运行的,但是要嘛图像歪斜要嘛看不到图像。如果以上一些设置成功,就能随心所欲绘制;

  5.glut中的消息响应在QT中都有各自的类;

  6.QT的类不比MFC类来的“苗条”,用到哪个查找哪个就ok。

  最后上代码。

功能说明文件:

 --use keyboard to control the cube
-w- accelerate the rolling speed;
-s- slow down the rolling speed;
-a- change the rolling direction;
-d- opposite with -a-;
-r- reset the initial state;
-c- change color

主函数文件:

 #include<QApplication>
#include"myglwidget.h"
int main(int argc,char *argv[])
{
QApplication MyApp(argc,argv);
MyGLWidget MyGL;
MyGL.show();
return MyApp.exec();
}

自定义GL类头文件:

 #ifndef MYGLWIDGET_H
#define MYGLWIDGET_H #include <QGLWidget>
#include<QTime>
#include<QTimerEvent>
#include<QKeyEvent>
class MyGLWidget : public QGLWidget
{
Q_OBJECT
public:
explicit MyGLWidget(QWidget *parent = ); signals:
private:
// GLfloat VertexData[24];
// GLubyte VertexIndex[6][4];
float m_rotate;
float m_speed;
bool m_angle;
GLubyte m_color_mode;
int m_T20msID;
void initializeGL();
void resizeGL(int w, int h);
void paintGL();
void timerEvent(QTimerEvent *);
void keyPressEvent(QKeyEvent *);
void Cross(GLfloat,GLubyte);
void ChangeColor(GLubyte mode,GLfloat value);
float GetRand(int,int);
void Draw(void);
void Cube(void);
public slots:
}; #endif // MYGLWIDGET_H

自定义GL类实现:

 #include "myglwidget.h"
static GLfloat VertexData[] = {
-0.5f, -0.5f, -0.5f,
0.5f, -0.5f, -0.5f,
-0.5f, 0.5f, -0.5f,
0.5f, 0.5f, -0.5f,
-0.5f, -0.5f, 0.5f,
0.5f, -0.5f, 0.5f,
-0.5f, 0.5f, 0.5f,
0.5f, 0.5f, 0.5f,
};
static GLubyte VertexIndex[][] = {
, , , ,
, , , ,
, , , ,
, , , ,
, , , ,
, , , ,
};
MyGLWidget::MyGLWidget(QWidget *parent) :
QGLWidget(parent)
{
m_speed = 2.0;
m_angle = ;
m_color_mode = ;
m_rotate = ;
m_T20msID = ;
}
void MyGLWidget::initializeGL()
{
glClearColor(,,,);
glClearDepth();
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
m_T20msID = startTimer();
qsrand(QTime::currentTime().msec());
}
void MyGLWidget::resizeGL(int w, int h)
{
glViewport(,,w,h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
if(w <= h)
glOrtho(-, , -(GLfloat)h/(GLfloat)w, (GLfloat)h/(GLfloat)w, -, );
else
glOrtho(-(GLfloat)w/(GLfloat)h, (GLfloat)w/(GLfloat)h, -, , -, );
}
void MyGLWidget::paintGL()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
Draw();
}
void MyGLWidget::Cube(void)
{
//enable vertex_array
glEnableClientState(GL_VERTEX_ARRAY);
//load vertex_array data
glVertexPointer(,GL_FLOAT,*sizeof(GLfloat),VertexData);
//drawing operation
glDrawElements(GL_QUADS,sizeof(VertexData),GL_UNSIGNED_BYTE,VertexIndex);
}
void MyGLWidget::timerEvent(QTimerEvent *event)
{
if(m_T20msID == event->timerId())
{
updateGL();
}
}
float MyGLWidget::GetRand(int start, int end)
{
return start + (end - start)*qrand()/(RAND_MAX + 1.0);
}
void MyGLWidget::Cross(GLfloat coordinater,GLubyte face)
{
GLfloat rand;
switch(face)
{
//front
case : rand = (GetRand(,)-)/;
glBegin(GL_LINES);
glVertex3f(-0.5f,rand,coordinater);
glVertex3f(0.5f,rand,coordinater);
glEnd();
rand = (GetRand(,)-)/;
glBegin(GL_LINES);
glVertex3f(rand,0.5f,coordinater);
glVertex3f(rand,-0.5f,coordinater);
glEnd();
break;
//left
case : rand = (GetRand(,)-)/;
glBegin(GL_LINES);
glVertex3f(coordinater,-0.5f,rand);
glVertex3f(coordinater,0.5f,rand);
glEnd();
rand = (GetRand(,)-)/;
glBegin(GL_LINES);
glVertex3f(coordinater,rand,0.5f);
glVertex3f(coordinater,rand,-0.5f);
glEnd();
break;
case : rand = (GetRand(,)-)/;
glBegin(GL_LINES);
glVertex3f(-0.5f,coordinater,rand);
glVertex3f(0.5f,coordinater,rand);
glEnd();
rand = (GetRand(,)-)/;
glBegin(GL_LINES);
glVertex3f(rand,coordinater,0.5f);
glVertex3f(rand,coordinater,-0.5f);
glEnd();
break;
default:break;
}
}
void MyGLWidget::Draw()
{
m_rotate += (m_angle)?m_speed:-m_speed;
glRotatef(m_rotate,,,);
glRotatef(m_rotate,,,);
glRotatef(m_rotate,,,);
glColor3f(,,);
//front-red
Cube();
int i;
for(i=;i<;i++)
{
//glColor3f(0,GetRand(0,33)/100,0);
ChangeColor(m_color_mode,GetRand(,)/);
glLineWidth(GetRand(,));
Cross(0.5f,);
}
//back-green
for(i=;i<;i++)
{
//glColor3f(0,GetRand(0,20)/100,0);
ChangeColor(m_color_mode,GetRand(,)/);
glLineWidth(GetRand(,));
Cross(-0.5f,);
}
//left-blue
for(i=;i<;i++)
{
//glColor3f(0,GetRand(46,66)/100,0);
ChangeColor(m_color_mode,GetRand(,)/);
glLineWidth(GetRand(,));
Cross(-0.5f,);
}
//right
for(i=;i<;i++)
{
//glColor3f(0,GetRand(33,66)/100,0);
ChangeColor(m_color_mode,GetRand(,)/);
glLineWidth(GetRand(,));
Cross(0.5f,);
}
//up
for(i=;i<;i++)
{
//glColor3f(0,GetRand(80,100)/100,0);
ChangeColor(m_color_mode,GetRand(,)/);
glLineWidth(GetRand(,));
Cross(0.5f,);
}
//bottom
for(i=;i<;i++)
{
//glColor3f(0,GetRand(66,100)/100,0);
ChangeColor(m_color_mode,GetRand(,)/);
glLineWidth(GetRand(,));
Cross(-0.5f,);
} }
void MyGLWidget::ChangeColor(GLubyte mode,GLfloat value)
{
switch(mode)
{
case :glColor3f(,value,);
break;
case :glColor3f(value,,);
break;
case :glColor3f(,,value);
break;
case :glColor3f(value,value,);
break;
case :glColor3f(value,,value);
break;
case :glColor3f(,value,value);
break;
case :glColor3f(value,value,value);
default:break;
}
}
void MyGLWidget::keyPressEvent(QKeyEvent *event)
{
switch(event->key())
{
case Qt::Key_A:m_angle = ;
break;
case Qt::Key_W:m_speed += 0.5;
break;
case Qt::Key_D:m_angle = ;
break;
case Qt::Key_S:if((m_speed-0.25)<)
m_speed = ;
else
m_speed -= 0.25;
break;
case Qt::Key_R:m_speed = ;
m_angle = ;
break;
case Qt::Key_C:if(m_color_mode == )
m_color_mode = ;
else
m_color_mode++;
break;
case Qt::Key_F:showFullScreen();
break;
case Qt::Key_Escape:close();
default:break;
}
}

OpenGL学习笔记5——嵌入Qt框架的更多相关文章

  1. OpenGL学习笔记3——缓冲区对象

    在GL中特别提出了缓冲区对象这一概念,是针对提高绘图效率的一个手段.由于GL的架构是基于客户——服务器模型建立的,因此默认所有的绘图数据均是存储在本地客户端,通过GL内核渲染处理以后再将数据发往GPU ...

  2. OpenGL学习笔记:拾取与选择

    转自:OpenGL学习笔记:拾取与选择 在开发OpenGL程序时,一个重要的问题就是互动,假设一个场景里面有很多元素,当用鼠标点击不同元素时,期待作出不同的反应,那么在OpenGL里面,是怎么知道我当 ...

  3. 并发编程学习笔记(12)----Fork/Join框架

    1. Fork/Join 的概念 Fork指的是将系统进程分成多个执行分支(线程),Join即是等待,当fork()方法创建了多个线程之后,需要等待这些分支执行完毕之后,才能得到最终的结果,因此joi ...

  4. QT入门学习笔记2:QT例程

    转至:http://blog.51cto.com/9291927/2138876 Qt开发学习教程 一.Qt开发基础学习教程 本部分博客主要根据狄泰学院唐老师的<QT实验分析教程>创作,同 ...

  5. tensorflow学习笔记——多线程输入数据处理框架

    之前我们学习使用TensorFlow对图像数据进行预处理的方法.虽然使用这些图像数据预处理的方法可以减少无关因素对图像识别模型效果的影响,但这些复杂的预处理过程也会减慢整个训练过程.为了避免图像预处理 ...

  6. OpenGL学习笔记2017/8/29

    OpenGL学习日志: 感谢doing5552 的OpenGL入门学习:http://www.cppblog.com/doing5552/archive/2009/01/08/71532.html 相 ...

  7. OpenGL学习笔记0——安装库

    最近需要做一个基于Zigbee室内无线定位的系统,受到TI公司ZigBee Sensor Monitor软件的启发,打算用OpenGL来做一个3D显示空间内物体位置的程序.学习阶段选择VS2010+O ...

  8. Jquery学习笔记1-jquery总体代码框架

    第一次在博客中记录自己的笔记,希望能坚持下去吧,加油! 今天学习的是Jquery的源代码,官网上下载,然后使用DW(dream waver)编辑器打开Js(下载的是未压缩版),版本是2.0.3.第一次 ...

  9. OpenGL学习笔记(1) 画一个三角形

    最近找实习有一丢丢蛋疼,沉迷鬼泣5,四周目通关,又不想写代码,写篇笔记复习一下,要好好学图形学啊 用OpenGL画一个三角形 项目的简介 记录一下跟着learnOpenGL学习的过程 笔记里的代码放在 ...

随机推荐

  1. CSS中的text-overflow:clip|ellipsis的使用

    如果想让某个容器(div或者li或者...块级元素)显示一行文字,当文字内容过多时,不换行,而是出现...,可以使用text-overflow:clip|ellipsis 基本语法:text-over ...

  2. (转)Spring AOP实现方式(转)

    我们可以通过三种方式来使用Spring AOP,它们分别是:@Aspect-based(Annotation),Schema-based(XML),以及底层的Spring AOP API 底层的Spr ...

  3. 声明提前js变量

    声明提前问题相关 js的变量声明语句无论出现在何处,都会先与其他代码首先被执行,使用var声明关键词声明变量的 作用于是当前的执行上下文,有可能是外围函数,或者,当变量声明在函数体之外时,则为全局变量 ...

  4. angular2 - content projection-

    angular2中的内容映射: App.component: <my-day> <my-lucky> </my-lucky> </my-day> MyD ...

  5. CSS3的nth-child(n)选择器学习

    写法:tr:nth-child(2),表示非tr的子元素中的第二个元素,并非从0开始计数,跟编程语言中的数组有区别. 参考网址:http://www.w3schools.com/cssref/sel_ ...

  6. 给linux安全模块LSM添加可链式调用模块(一)

    前些日子接了个外包的活,了解了一下Linux安全模块,发现了安全模块中的一些问题. 关于linux安全模块LSM在此就不多说了,大家google下就明白了. 这里主要介绍的是如何修改这个模块,使它可链 ...

  7. 渗透编码转码转换工具:CodeFuns

    功能: 1 支持10 进制 16进制 数字的互相转换 2 对字符串进行倒叙 3 ASCII转换,反转 4 生成MSSQL的char函数ASCII字符串,反转 5 生成PHP的CHR函数ASCII字符串 ...

  8. mouseover事件与mouseenter事件的区别

    不论鼠标指针穿过被选元素或其子元素,都会触发 mouseover 事件.对应mouseout 只有在鼠标指针穿过被选元素时,才会触发 mouseenter 事件.对应mouseleave 被触发的 M ...

  9. 好的bootstrap文章

    http://www.cnblogs.com/gamehiboy/p/5176618.html http://www.cnblogs.com/landeanfen/p/5821192.html htt ...

  10. Java中的队列Queue,优先级队列PriorityQueue

    队列Queue 在java5中新增加了java.util.Queue接口,用以支持队列的常见操作.该接口扩展了java.util.Collection接口. Queue使用时要尽量避免Collecti ...