OpenGL学习笔记5——嵌入Qt框架
学习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框架的更多相关文章
- OpenGL学习笔记3——缓冲区对象
在GL中特别提出了缓冲区对象这一概念,是针对提高绘图效率的一个手段.由于GL的架构是基于客户——服务器模型建立的,因此默认所有的绘图数据均是存储在本地客户端,通过GL内核渲染处理以后再将数据发往GPU ...
- OpenGL学习笔记:拾取与选择
转自:OpenGL学习笔记:拾取与选择 在开发OpenGL程序时,一个重要的问题就是互动,假设一个场景里面有很多元素,当用鼠标点击不同元素时,期待作出不同的反应,那么在OpenGL里面,是怎么知道我当 ...
- 并发编程学习笔记(12)----Fork/Join框架
1. Fork/Join 的概念 Fork指的是将系统进程分成多个执行分支(线程),Join即是等待,当fork()方法创建了多个线程之后,需要等待这些分支执行完毕之后,才能得到最终的结果,因此joi ...
- QT入门学习笔记2:QT例程
转至:http://blog.51cto.com/9291927/2138876 Qt开发学习教程 一.Qt开发基础学习教程 本部分博客主要根据狄泰学院唐老师的<QT实验分析教程>创作,同 ...
- tensorflow学习笔记——多线程输入数据处理框架
之前我们学习使用TensorFlow对图像数据进行预处理的方法.虽然使用这些图像数据预处理的方法可以减少无关因素对图像识别模型效果的影响,但这些复杂的预处理过程也会减慢整个训练过程.为了避免图像预处理 ...
- OpenGL学习笔记2017/8/29
OpenGL学习日志: 感谢doing5552 的OpenGL入门学习:http://www.cppblog.com/doing5552/archive/2009/01/08/71532.html 相 ...
- OpenGL学习笔记0——安装库
最近需要做一个基于Zigbee室内无线定位的系统,受到TI公司ZigBee Sensor Monitor软件的启发,打算用OpenGL来做一个3D显示空间内物体位置的程序.学习阶段选择VS2010+O ...
- Jquery学习笔记1-jquery总体代码框架
第一次在博客中记录自己的笔记,希望能坚持下去吧,加油! 今天学习的是Jquery的源代码,官网上下载,然后使用DW(dream waver)编辑器打开Js(下载的是未压缩版),版本是2.0.3.第一次 ...
- OpenGL学习笔记(1) 画一个三角形
最近找实习有一丢丢蛋疼,沉迷鬼泣5,四周目通关,又不想写代码,写篇笔记复习一下,要好好学图形学啊 用OpenGL画一个三角形 项目的简介 记录一下跟着learnOpenGL学习的过程 笔记里的代码放在 ...
随机推荐
- React 学习笔记(学习地址汇总)
好的博文地址:http://www.ruanyifeng.com/blog/2015/03/react.html 官网学习地址:http://facebook.github.io/react/docs ...
- 利用linux漏洞进行提权
RHEL5—RHEL6下都可以提权 本人测试环境CenOS6.5:该方法只能用作与有root用户切换到普通用户的环境,如果是普通用户直接登录在执行最后一步的时候直接退出登录 $ mkdir /tmp/ ...
- 浏览器与HTML5的相辅相成
浏览器与HTML5的相辅相成 往往一项技术的更新和发展并不是单一性的,浏览器和HTML5技术的发展亦是如此,而它们的进步也带动了整个行业的变化.浏览器与HTML5相辅相成的关系也让我们的网页能够实现更 ...
- 11.12模拟考T1(可持续优化)PS:神奇的东西
1.数列操作 (array.pas/c/cpp) [问题描述] 现在有一个数列,最初包含0个数.现在要对数列操作n次,操作有3类. 1) a k,在数列的最后插入一个整数k 2) s 将最近插入的 ...
- https/相对路径,绝对路径
1. htttps HTTPS(全称:Hyper Text Transfer Protocol over Secure Socket Layer),是以安全为目标的HTTP通道,简单讲是HTTP的安全 ...
- LeetCode 【318. Maximum Product of Word Lengths】
Given a string array words, find the maximum value of length(word[i]) * length(word[j]) where the tw ...
- JPanel
class NewPanel extends JPanel{ public NewPanel() {} public void paintComponent(Graphics g) { int x=0 ...
- 记一次ifconfig命令
由于Windows 10的强制更新,原来的Virtual box Host-Only驱动莫名奇妙的不见了,于是上网找各种解决方案: 1.重新生成虚拟网卡适配器:执行 VBoxManage.exe ho ...
- linux根文件系统制作
在嵌入式中移植的内核下载到开发板上,是没有办法真正的启动Linux操作系统的,会出现无法加载文件系统的错误. 那么根文件系统在系统启动中到底是什么时候挂载的呢?先将/dev/ram0挂载,而后执行/l ...
- Win7下搭建VPN服务器教程
前言:VPN就是一个中转器,移动网要访问外网,外网是网通的,没使用VPN的情况下我们就不能访问外网,这时候VPN就把我们的移动网自动转成能和外网连接所匹配的网,就实现了所谓的(fanqiang). 一 ...