使用Qt进行OpenGL编程OpenGL programming withQt [1]

12 篇文章 1 订阅

  正如我们所知,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

main.cpp-------------------

//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());
}

MainWidget.h---------------------------

#include <QGLWidget>

class CMainWidget : public QGLWidget {
	Q_OBJECT
private:

public:
	CMainWidget();
	~CMainWidget();

protected:
	void initializeGL();
	void paintGL();
	void resizeGL(int iWidth,int iHeight);
};

MainWidget.cpp---------------------------

#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带来的不是效率的提升,而是灵活性和部署效率的提升。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值