正如我们所知,opengl只会提供3D渲染和少量(甚至没有)GUI图形编程的接口。因此创建图形交互界面是我们使用opengl进行编程的第一步。诚如各平台所言,它们都提供了原声的图形交互界面的编程接口,由于众所周知的原因,各个平台提供的接口都是不可移植的,于是我在这里选择了Qt这个图形编程库,使得我的opengl应用真正地成为一个可移植的应用程式。
首先我会假设你已经知道了一些关于Qt编程的基本知识,这包括pro文件(qmake的配置文件)的编写。
本文所采用的Qt库的版本是Qt5.1.0,是从2013-03-29的git上checkout下来的,并且使用了vs2012进行了静态编译。opengl是Qt内置的。
基于某些个人编程的偏好原因,我并没有使用vs2012 IDE或者qt creator完成这个本文这个demo的编写。我使用一个叫sublime text2的编辑器进行编码(它的包扩展和对齐线使我非常喜欢它),在桌面上建立了一个bat的批处理脚本
Qt510VS11.bat
SET PATH=%PATH%;X:\Qt\Qt5\Qt510\StaticVS11x86\bin;X:\Qt\toolChain;C:\cygwin\bin;C:\Program Files (x86)\Windows Kits\8.0\Debuggers\x86;
x:
title="Qt 5.1.0 Static VS11 x86"
%comspec% /k ""C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\vcvarsall.bat"" x86
cmd
这个路径:X:\Qt\toolChain,是我个人在团队内发起的一个基于Qt的跨平台基础库,诸君可不必理会。
另外,由于VS2012对xp平台的支持问题,我另外建立了一个bat文件在X:\Qt\toolChain目录下
v110_xpPlatformToolset.bat
set INCLUDE=%ProgramFiles(x86)%\Microsoft SDKs\Windows\7.1A\Include;%INCLUDE%
set PATH=%ProgramFiles(x86)%\Microsoft SDKs\Windows\7.1A\Bin;%PATH%
set LIB=%ProgramFiles(x86)%\Microsoft SDKs\Windows\7.1A\Lib;%LIB%
set CL=/D_USING_V110_SDK71_;%CL%
//set LINK=/SUBSYSTEM:WINDOWS,5.01
这个脚本的最后一行有问题,我把它破坏掉了。。。。
执行这个脚本后,在pro文件内给链接器添加/SUBSYSTEM:WINDOWS,5.01的选项,即可让编译出来的应用程序可在xp下执行。
这个demo包括以下文件,helloOpenGL.pro,main.cpp,MainWidget.h,MainWidget.cpp
文件层次如下:
|--helloOpenGL
|helloOpenGL.pro
|main.cpp
|--gui
|MainWidget.h
|MainWidget.cpp
文件内容如下:
helloOpenGL.pro--------------------
QT += gui opengl TEMPLATE = app TARGET = helloOpenGL INCLUDEPATH += X:\\Qt\\toolChain DEPENDPATH += X:\\Qt\\toolChain\\fdb #linux/unix gcc compliler contains(QMAKE_CXX,g++) { message(g++ compiler) Debug { DESTDIR = GCCDebug OBJECTS_DIR = $$DESTDIR\\.obj MOC_DIR = $$DESTDIR\\.moc RCC_DIR = $$DESTDIR\\.rcc UI_DIR = $$DESTDIR\\.ui } Release { DESTDIR = GCCRlease OBJECTS_DIR = $$DESTDIR\\.obj MOC_DIR = $$DESTDIR\\.moc RCC_DIR = $$DESTDIR\\.rcc UI_DIR = $$DESTDIR\\.ui } QMAKE_CXXFLAGS += -std=c++0x CONFIG += -static #for linux static link QMAKE_RPATHDIR += ./libs } #win32 cl compiler contains(QMAKE_CXX,cl) { #微软的编译器,同时也说明了这是Windows message(cl compiler) Debug { DESTDIR = Win32Debug OBJECTS_DIR = $$DESTDIR\\.obj MOC_DIR = $$DESTDIR\\.moc RCC_DIR = $$DESTDIR\\.rcc UI_DIR = $$DESTDIR\\.ui } Release { DESTDIR = Win32Rlease OBJECTS_DIR = $$DESTDIR\\.obj MOC_DIR = $$DESTDIR\\.moc RCC_DIR = $$DESTDIR\\.rcc UI_DIR = $$DESTDIR\\.ui } QMAKE_LFLAGS += /MANIFESTUAC:\"level=\'requireAdministrator\' uiAccess=\'false\'\" /SUBSYSTEM:WINDOWS,5.01 QMAKE_POST_LINK += mt -manifest '$$DESTDIR\\$$TARGET'.exe.embed.manifest -outputresource:$$BINARY_PATH } #macox clang compiler PLATFORM=$$system(uname -s) #set macx-clang flags contains(PLATFORM,Darwin) { contains(QMAKE_CXX,clang++) { message(Darwin + clang++ - set:QMAKE_CXXFLAGS += -std=c++0x -stdlib=c++ -mmacosx-version-min=10.7) Debug { DESTDIR = DarwinDebug OBJECTS_DIR = $$DESTDIR\\.obj MOC_DIR = $$DESTDIR\\.moc RCC_DIR = $$DESTDIR\\.rcc UI_DIR = $$DESTDIR\\.ui } Release { DESTDIR = DarwinRlease OBJECTS_DIR = $$DESTDIR\\.obj MOC_DIR = $$DESTDIR\\.moc RCC_DIR = $$DESTDIR\\.rcc UI_DIR = $$DESTDIR\\.ui } QMAKE_CXXFLAGS += -std=c++0x -stdlib=libc++ -mmacosx-version-min=10.7 } } # Input SOURCES += main.cpp #gui HEADERS += gui/MainWidget.h SOURCES += gui/MainWidget.cpp #//gui
//qt library #include <QApplication> //user #include "gui/MainWidget.h" int main(int argc,char* argv[]) { QApplication app(argc,argv); CMainWidget* pMainWidget = new CMainWidget(); pMainWidget->show(); return (app.exec()); }
#include <QGLWidget> class CMainWidget : public QGLWidget { Q_OBJECT private: public: CMainWidget(); ~CMainWidget(); protected: void initializeGL(); void paintGL(); void resizeGL(int iWidth,int iHeight); };
#include "MainWidget.h" CMainWidget::CMainWidget() { this->setGeometry(50,50,320,240); this->setWindowTitle(QString("Hello OpenGL")); } CMainWidget::~CMainWidget() { } void CMainWidget::initializeGL() { glClearColor(0.0,0.0,0.0,0.0); } void CMainWidget::paintGL() { glClear(GL_COLOR_BUFFER_BIT); } void CMainWidget::resizeGL(int iWidth,int iHeight) { }
这就是一个最小规模的使用Qt+OpenGL编写的demo了
打开前面的Qt510VS11.bat,到这个工程的根目录
执行
qmake helloOpenGL.pro
jom /j 8 (这是我放在toolChain下的一个nmake的替代品,它可以提供并行编译,如果你没有的话可以简单的执行nmake)
没有报错的话你就可以在Win32Debug目录下看到一个helloOpenGL.exe的应用程式了
如果你想发布
jom -f Makefile.Release /j 8(或者nmake -f Makefile.Release)
就可以。
后记:有人可能说了,听说Qt效率不怎么高,能应付3D渲染这种高效率的活吗?是的,Qt在GUI上的效率和原生GUI的效率确实没得比,但除非你以光速在UI上面进行操作,这个时候Qt的基于信号-槽的机制可能就捉襟见肘了,其余的时候还是应付得过来的,我使用Qt编程两年了,还没碰到过UI线程是因为纯粹的操作导致的响应不过来,多半时候是因为程序员在UI的线程上干逻辑层的活。另外基于Qt编写的UI动画也能非常流畅地运行,这些是在我所部署的四种平台上得到的验证(windows,linux,mac,andriod)。再说到前面的问题,3D渲染实际上在这里是由opengl完成的,跟qt没多大关系。qt带来的不是效率的提升,而是灵活性和部署效率的提升。