【推荐】2019 Java 开发者跳槽指南.pdf(吐血整理) >>>
一、安装必要的库
sudo apt-get install libxt-dev libmotif-dev libxext-dev libxaw7-dev libxmu-dev libgl1-mesa-dev freeglut3-dev libglu1-mesa-dev libqt4-dev libqt4-opengl-dev
二、项目openglQt(目录下)的文件:
$ cat openglQt.pro
######################################################################
# Automatically generated by qmake (2.01a) ?? 11? 19 22:49:56 2014
######################################################################
QT += opengl
TEMPLATE = app
TARGET =
DEPENDPATH += .
INCLUDEPATH += .
LIBS += -lGLU -lglut
# Input
HEADERS += nehewidget.h
SOURCES += main.cpp nehewidget.cpp
$ cat nehewidget.h
/* NeHeWidget类
* 这就是我们继承QGLWidget类得到的OpenGL窗口部件类。
* 由nehewidget.h 展开。
*/
#include <QtOpenGL/QtOpenGL>
class NeHeWidget : public QGLWidget
{
/*因为QGLWidget类被包含在qgl.h头文件中,所以我们的类就需要包含这个头文件。Q_OBJECT是Qt中的一
*个专用的宏,具体说明请参见Qt的文档。
*/
Q_OBJECT
public:
NeHeWidget( QWidget* parent = 0, bool fs = false );
~NeHeWidget();
protected:
void initializeGL();
void paintGL();
/*因为QGLWidget类已经内置了对OpenGL的处理,就是通过对initializeGL()、paintGL()和resizeGL()
*这个三个函数实现的,具体情况可以参考QGLWidget类的文档。因为我们的这个Qt OpenGL教程取材于
*NeHe OpenGL教程,所以这里就用这个NeHeWidget类来继承QGLWidget类来使用相关OpenGL的功能。
*initializeGL()是用来初始化这个OpenGL窗口部件的,可以在里面设定一些有关选项。paintGL()就是用
*来绘制OpenGL的窗口了,只要有更新发生,这个函数就会被调用。resizeGL()就是用来处理窗口大小变化这
*一事件的,width和height就是新的大小状态下的宽和高了,另外resizeGL()在处理完后会自动刷新屏幕。
*/
void resizeGL( int width, int height );
/*这是Qt里面的鼠标按下事件处理函数。*/
void keyPressEvent( QKeyEvent *e );
protected:
/*用来保存窗口是否处于全屏状态的变量。*/
bool fullscreen;
};
$ cat nehewidget.cpp
/* 由nehewidget.cpp 展开。
*/
#include "nehewidget.h"
#include <GL/glut.h>
/*这个是构造函数,parent就是父窗口部件的指针,fs就是窗口是否最大化。*/
NeHeWidget::NeHeWidget( QWidget* parent,bool fs )
: QGLWidget( parent)
{
/*保存窗口是否为全屏的状态。*/
fullscreen = fs;
/*设置窗口的位置,即左上角为(0,0)点,大小为640*480。*/
setGeometry( 0, 0, 640, 480 );
/*设置窗口的标题为“NeHe's OpenGL Framework”。*/
setWindowTitle(tr("NeHe's OpenGL Framework"));
/*如果fullscreen为真,那么就全屏显示这个窗口。*/
if ( fullscreen )
showFullScreen();
}
/*这个是析构函数。*/
NeHeWidget::~NeHeWidget()
{
}
/*这个函数中,我们对OpenGL进行所有的设置。我们设置清除屏幕所用的颜色,打开深度缓存,启用smooth
* shading(阴影平滑),等等。这个例程直到OpenGL窗口创建之后才会被调用。
*/
void NeHeWidget::initializeGL()
{
/*这一行启用smooth shading(阴影平滑)。阴影平滑通过多边形精细的混合色彩,并对外部光进行平滑。
*我将在另一个教程中更详细的解释阴影平滑。
*/
glShadeModel( GL_SMOOTH );
/*这一行设置清除屏幕时所用的颜色。如果您对色彩的工作原理不清楚的话,我快速解释一下。
*色彩值的范围从0.0到1.0。0.0代表最黑的情况,1.0就是最亮的情况。glClearColor后的
*第一个参数是红色,第二个是绿色,第三个是蓝色。最大值也是1.0,代表特定颜色分量的最亮情况。
*最后一个参数是Alpha值。当它用来清除屏幕的时候,我们不用关心第四个数字。现在让它为0.0。
*我会用另一个教程来解释这个参数。通过混合三种原色(红、绿、蓝),您可以得到不同的色彩。
*希望您在学校里学过这些。因此当您使用glClearColor(0.0, 0.0, 1.0, 0.0 ),您将用亮蓝色清除
*屏幕。如果用glClearColor(0.5, 0.0, 0.0, 0.0 ) *的话,您将使用中红色来清除屏幕。
*不是最亮(1.0),也不是最暗 (0.0)。要得到白色背景,您应该将所有的
*颜色设成最亮(1.0)。要黑色背景的话,您该将所有的颜色设为最暗(0.0)。
*/
glClearColor( 0.0, 0.0, 0.0, 0.0 );
/*设置深度缓存。*/
glClearDepth( 1.0 );
/*启用深度测试。*/
glEnable( GL_DEPTH_TEST );
/*所作深度测试的类型。*/
/*上面这三行必须做的是关于depth buffer(深度缓存)的。将深度缓存设想为屏幕后面的层。深度缓存
*不断的对物体进入屏幕内部有多深进行跟踪。我们本节的程序其实没有真正使用深度缓存,但几乎所有在
*屏幕上显示3D场景OpenGL程序都使用深度缓存。它的排序决定那个物体先画。这样您就不会将一个圆形
*后面的正方形画到圆形上来。深度缓存是OpenGL十分重要的部分。
*/
glDepthFunc( GL_LEQUAL );
/*真正精细的透视修正。这一行告诉OpenGL我们希望进行最好的透视修正。这会十分轻微的影响性能。
*但使得透视图看起来好一点。
*/
glHint( GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST );
}
/*这个函数中包括了所有的绘图代码。任何您所想在屏幕上显示的东东都将在此段代码中出现。以后的
*每个教程中我都会在例程的此处增加新的代码。如果您对 OpenGL已经有所了解的话,您可以在
*glLoadIdentity()调用之后,函数返回之前,试着添加一些OpenGL代码来创建基本的形。如果您是
*OpenGL新手,等着我的下个教程。目前我们所作的全部就是将屏幕清除成我们前面所决定的颜色,
*清除深度缓存并且重置场景。我们仍没有绘制任何东东。
*/
void NeHeWidget::paintGL()
{
/*清楚屏幕和深度缓存。*/
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
/*重置当前的模型观察矩阵。*/
glLoadIdentity();
}
/*透视图设置屏幕。意味着越远的东西看起来越小。这么做创建了一个现实外观的场景。此处透
*视按照基于窗口宽度和高度的45度视角来计算。0.1,100.0是我们在场景中所能绘制深度的起点和终点。
*glMatrixMode(GL_PROJECTION)指明接下来的两行代码将影响projection matrix(投影矩阵)。投影
*矩阵负责为我们的场景增加透视。 glLoadIdentity()近似于重置。它将所选的矩阵状态恢复成其原始状态。
*调用glLoadIdentity()之后我们为场景设置透视图。glMatrixMode(GL_MODELVIEW)指明任何新的变换
*将会影响modelview matrix(模型观察矩阵)。模型观察矩阵中存放了我们的物体讯息。最后我们重置
*模型观察矩阵。如果您还不能理解这些术语的含义,请别着急。在以后的教程里,我会向大家解释。只要
*知道如果您想获得一个精彩的透视场景的话,必须这么做。这个函数的作用是重新设置OpenGL场景的
*大小,而不管窗口的大小是否已经改变(假定您没有使用全屏模式)。甚至您无法改变窗口的大小时
*(例如您在全屏模式下),它至少仍将运行一次——在程序开始时设置我们的透视图。OpenGL场景的尺寸
*将被设置成它显示时所在窗口的大小。
*/
void NeHeWidget::resizeGL( int width, int height )
{
/*防止height为0。*/
if ( height == 0 )
height = 1;
/*重置当前的视口(Viewport)。*/
glViewport( 0, 0, (GLint)width, (GLint)height );
/*选择投影矩阵.*/
glMatrixMode( GL_PROJECTION );
/*重置投影矩阵。*/
glLoadIdentity();
/*建立透视投影矩阵。*/
gluPerspective( 45.0, (GLfloat)width/(GLfloat)height, 0.1, 100.0 );
/*选择模型观察矩阵。*/
glMatrixMode( GL_MODELVIEW );
/*重置模型观察矩阵。*/
glLoadIdentity();
}
void NeHeWidget::keyPressEvent( QKeyEvent *e )
{
switch ( e->key() )
{
/*如果按下了F2键,那么屏幕是否全屏的状态就切换一次。然后再根据需要,显示所要的
*全屏窗口或者普通窗口。
*/
case Qt::Key_F2:
fullscreen = !fullscreen;
if ( fullscreen )
showFullScreen();
else
{
showNormal();
setGeometry( 0, 0, 640, 480 );
}
update();
break;
/*如果按下了Escape键,程序退出。*/
case Qt::Key_Escape:
close();
}
}
$ cat main.cpp
/* main.cpp
* 由main.cpp 展开。
*/
/* Qt的应用程序直接使用QtGui模块,直接包含QtGui就可以了。*/
#include <QtGui>
#include "nehewidget.h"
int main( int argc, char **argv )
{
/*我们把这个布尔型变量的初始值设置为false。*/
bool fs = false;
/*每一个Qt应用程序都使用QApplication类。*/
QApplication a(argc,argv);
/*使用当前字符编码。*/
QTextCodec::setCodecForTr(QTextCodec::codecForLocale());
/*这里弹出一个消息对话框,让用户选择是否使用全屏模式。*/
switch( QMessageBox::information( 0,
"Start FullScreen?",
"Would You Like To Run In Fullscreen Mode?",
QMessageBox::Yes,
QMessageBox::No | QMessageBox::Default ) )
{
case QMessageBox::Yes:
fs = true;
break;
case QMessageBox::No:
fs = false;
break;
}
/*设置应用程序的主窗口部件为w。*/
NeHeWidget w( 0, fs );
/*显示w。*/
w.show();
/*程序返回。*/
return a.exec();
}
三、编译
$ qmake
$ make
g++ -c -m64 -pipe -O2 -Wall -W -D_REENTRANT -DQT_NO_DEBUG -DQT_OPENGL_LIB -DQT_GUI_LIB -DQT_CORE_LIB -DQT_SHARED -I/usr/share/qt4/mkspecs/linux-g++-64 -I. -I/usr/include/qt4/QtCore -I/usr/include/qt4/QtGui -I/usr/include/qt4/QtOpenGL -I/usr/include/qt4 -I. -I/usr/X11R6/include -I. -o main.o main.cpp
g++ -c -m64 -pipe -O2 -Wall -W -D_REENTRANT -DQT_NO_DEBUG -DQT_OPENGL_LIB -DQT_GUI_LIB -DQT_CORE_LIB -DQT_SHARED -I/usr/share/qt4/mkspecs/linux-g++-64 -I. -I/usr/include/qt4/QtCore -I/usr/include/qt4/QtGui -I/usr/include/qt4/QtOpenGL -I/usr/include/qt4 -I. -I/usr/X11R6/include -I. -o nehewidget.o nehewidget.cpp
/usr/lib/x86_64-linux-gnu/qt4/bin/moc -DQT_NO_DEBUG -DQT_OPENGL_LIB -DQT_GUI_LIB -DQT_CORE_LIB -DQT_SHARED -I/usr/share/qt4/mkspecs/linux-g++-64 -I. -I/usr/include/qt4/QtCore -I/usr/include/qt4/QtGui -I/usr/include/qt4/QtOpenGL -I/usr/include/qt4 -I. -I/usr/X11R6/include -I. nehewidget.h -o moc_nehewidget.cpp
g++ -c -m64 -pipe -O2 -Wall -W -D_REENTRANT -DQT_NO_DEBUG -DQT_OPENGL_LIB -DQT_GUI_LIB -DQT_CORE_LIB -DQT_SHARED -I/usr/share/qt4/mkspecs/linux-g++-64 -I. -I/usr/include/qt4/QtCore -I/usr/include/qt4/QtGui -I/usr/include/qt4/QtOpenGL -I/usr/include/qt4 -I. -I/usr/X11R6/include -I. -o moc_nehewidget.o moc_nehewidget.cpp
g++ -m64 -Wl,-O1 -o openglQt main.o nehewidget.o moc_nehewidget.o -L/usr/lib/x86_64-linux-gnu -L/usr/X11R6/lib64 -lGLU -lglut -lQtOpenGL -lQtGui -lQtCore -lGL -lpthread
来源:oschina
链接:https://my.oschina.net/u/2245781/blog/3152793