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学习的过程 笔记里的代码放在 ...
随机推荐
- HTML5 地理位置定位(HTML5 Geolocation)原理及应用
地理位置(Geolocation)是 HTML5 的重要特性之一,提供了确定用户位置的功能,借助这个特性能够开发基于位置信息的应用.今天这篇文章向大家介绍一下 HTML5 地理位置定位的基本原理及各个 ...
- Django 创建APP简单步骤
yum install epel-releaseyum install python34yum install python-pippip install django django-admin st ...
- 修改oracle实例名orcl为demo
修改oracle实例名有六步: 1.sqlplus username/password as sysdba登陆,然后从spfile文件创建pfile文件 :create pfile from spfi ...
- 解决Eclipse中文乱码 - 技术博客 - 51CTO技术博客 http://hsj69106.blog.51cto.com/1017401/595598/
解决Eclipse中文乱码 - 技术博客 - 51CTO技术博客 http://hsj69106.blog.51cto.com/1017401/595598/
- Android 图片上传
上传方式:两种 1:Base64() (1):获取图片路径,将图片转为String 类型 (2):通过post提交的方式.以键值对的方式上传到服务器,和一般的提交关键字没有任何区别. (3):这种 ...
- js中cookie的使用详细分析
JavaScript中的另一个机制:cookie,则可以达到真正全局变量的要求. cookie是浏览器 提供的一种机制,它将document 对象的cookie属性提供给JavaScript.可以由J ...
- webstorm 10 出现不能run cordova项目
could not create the java virtual machine Error occurred during initialization of VM Could not reser ...
- bootstrap学习
1. bootstrap使用了less作为预编译器,他是结构清晰层次分明的css页面构建样式,即使你不喜欢bootstrap的样式,你仍然可以借鉴bootstrap编写css的这种方式 2.boots ...
- C#中dynamic的正确用法
C#中dynamic的正确用法 http://www.cnblogs.com/qiuweiguo/archive/2011/08/03/2125982.html dynamic是FrameWork4 ...
- 【新手】python爬虫遍历贴吧用户
想法是遍历学校贴吧的用户,获取用户的数据用来分析,因为是初学python,就一点一点的写,变量命名也不规范,见谅 系统:windows 版本:python 3.5 #获取河北大学工商学院吧1000页以 ...