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学习的过程 笔记里的代码放在 ...
随机推荐
- 莱卡旗下旗下首台全片幅无反相机 Leica SL 抵港,吐槽下
http://cn.engadget.com/2015/11/18/leica-sl-hk-hands-on/#continued 单机+单镜头=7.5W¥,如果再来个定焦共10W¥+:有心杀贼,无力 ...
- 写一些封装part1 (事件绑定移除,圆形矩形碰撞检测)
var EventHandle = { addEvent:function(ele,type,handle){ if (ele.addEventListener) { ele.addEventList ...
- this其实是js的一个对象谁调用它它就指向谁
本人看了一下,感觉对this解释的有点复杂了,因此,本人在此给this一个简单易于理解的定义. 因为上面计算出来的结果不符合我们的习惯,并且负值在计算的时候会影响正确性,现在我们给这个结果加上180 ...
- bx, bp, si, di寄存器的使用规则
首先,都可以单独使用. 另外,组合使用的情况下: 记住这张图片就行了=_= 意思就是,bx只能和si,di组合.bp只能和si,di组合.
- redis入门笔记(2)
redis入门笔记(2) 上篇文章介绍了redis的基本情况和支持的数据类型,本篇文章将介绍redis持久化.主从复制.简单的事务支持及发布订阅功能. 持久化 •redis是一个支持持久化的内存数据库 ...
- WIN7下搭建CORDOVA环境
Cordova 环境搭建 1安装JDK 工具文件夹中:jdk目录 1)下载地址:http://www.oracle.com/technetwork/java/javase/downloads/inde ...
- app后端设计(12)--图片的处理
app上线后,不断接受用户的反馈,于是,反馈非常差的情况下,都会有app的改版. 一旦app的改版,都会有比较大的UI改动,一改动UI,那么图片的尺寸也就必须要改变. 在app后端设计(1)—api( ...
- Java 使用Memcache
使用spymemcached.jar public class MemcachedJava { public static void main(String[] args) { try { // 连接 ...
- QQ通信原理及QQ是怎么穿透内网进行通信的? (转)
原:http://f543711700.iteye.com/blog/978044#bc2344608 QQ是一个基于TCP/UDP协议的通讯软件 发送消息的时候是UDP打洞,登陆的时候使用HTTP~ ...
- Inno Setup怎样创建一个自动申请管理员身份运行的快捷
如果你使用的是 Unicode 版本的 Inno Setup,那么以下是更为专业的解决方法. 这是 mlaan 提及的再一种方法. QUOTE( CodeAutomation3.iss) ...