前两天本人介绍了QT环境的搭建方法及简单程序的调试,可能讲得不太详细(没图,看文字不太直观,
但是现在我还是没搞明白CSDN怎么个发图法),几天我向大家介绍如何在qt中进行OpenGL编程。
因为Qt里面已经集成了OpenGL所以直接使用就可以了,但是我在调试的过程中也遇到了很多麻烦,老是
链接错误,于是我又重新在VS2005中添加了OpenGL的头文件及链接库等,这才编译通过,比较麻烦~
VS2005中配置OpenGL的方法:
Windows环境下的GLUT下载地址:(大小约为150k)
http://www.opengl.org/resources/libraries/glut/glutdlls37beta.zip
无法从以上地址下载的话请使用下面的连接:
http://upload.programfan.com/upfile/200607311626279.zip
Windows环境下安装GLUT的步骤:
1、将下载的压缩包解开,将得到5个文件
2、以我的安装目录为例:
(1)“D:/Software/VS2005 Team Suite/VC/include/GL文件夹”。把解压得到的glut.h放到这个GL文件
夹里。没有GL文件夹可以自己建一个,一般都有的。
(2)“D:/Software/VS2005 Team Suite/VC/lib文件夹”)。把解压得到的glut.lib和glut32.lib放到
静态函数库所在文件夹,即lib文件夹。
(3)把解压得到的glut.dll和glut32.dll放到操作系统目录下面的system32文件夹内。(典型的位置为
:C:/Windows/System32)这是非常重要的动态链接库设置!
然后就是象上一篇文章一样找个.bmp图片,我的OpenGL的程序是来自
http://www.chinagcn.com/bbs/viewthread.php?tid=2487里的第7个文章-8楼的那个例子,不过稍有改动
,代码如下:
nehewidget.h文件
/*
Qt OpenGL Tutorial - Lesson 07
nehewidget.h
v 1.00
2002/12/19
Copyright (C) 2002 Cavendish
cavendish@qiliang.net
http://www.qiliang.net/nehe_qt
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
*/
#ifndef NEHEWIDGET_H
#define NEHEWIDGET_H
#include <Qt/qgl.h>
class NeHeWidget : public QGLWidget
{
Q_OBJECT
public:
NeHeWidget( QWidget* parent = 0, const char* name = 0, bool fs = false );
~NeHeWidget();
protected:
void initializeGL();
void paintGL();
void resizeGL( int width, int height );
void keyPressEvent( QKeyEvent *e );
void loadGLTextures();
protected:
bool fullscreen;
GLfloat xRot, yRot, zRot;
GLfloat zoom;
GLfloat xSpeed, ySpeed;
GLuint texture[3];
GLuint filter;
bool light;
};
#endif//NEHEWIDGET_H
nehewidget.cpp文件
/*
Qt OpenGL Tutorial - Lesson 07
nehewidget.cpp
v 1.00
2002/12/19
Copyright (C) 2002 Cavendish
cavendish@qiliang.net
http://www.qiliang.net/nehe_qt
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
*/
#include <QtGui/QApplication>
#include <QtGui/QMainWindow>
#include <QtGui/QWidget>
#include <QtGui/QImage.h>
#include <QtGui/qevent.h>
#include "nehewidget.h"
GLfloat lightAmbient[4] = { 0.5, 0.5, 0.5, 1.0 };
GLfloat lightDiffuse[4] = { 1.0, 1.0, 1.0, 1.0 };
GLfloat lightPosition[4] = { 0.0, 0.0, 2.0, 1.0 };
NeHeWidget::NeHeWidget( QWidget* parent, const char* name, bool fs )
: QGLWidget( parent/*, name */)
{
xRot = yRot = zRot = 0.0;
zoom = -5.0;
xSpeed = ySpeed = 0.0;
filter = 0;
light = false;
fullscreen = fs;
setGeometry( 100, 100, 640, 480 );
//setCaption("NeHe's Texture, Lighting & Keyboard Tutorial");
if ( fullscreen )
showFullScreen();
}
NeHeWidget::~NeHeWidget()
{
}
void NeHeWidget::paintGL()
{
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
glLoadIdentity();
glTranslatef( 0.0, 0.0, zoom );
glRotatef( xRot, 1.0, 0.0, 0.0 );
glRotatef( yRot, 0.0, 1.0, 0.0 );
glBindTexture( GL_TEXTURE_2D, texture[filter] );
glBegin( GL_QUADS );
glNormal3f( 0.0, 0.0, 1.0 );
glTexCoord2f( 0.0, 0.0 ); glVertex3f( -1.0, -1.0, 1.0 );
glTexCoord2f( 1.0, 0.0 ); glVertex3f( 1.0, -1.0, 1.0 );
glTexCoord2f( 1.0, 1.0 ); glVertex3f( 1.0, 1.0, 1.0 );
glTexCoord2f( 0.0, 1.0 ); glVertex3f( -1.0, 1.0, 1.0 );
glNormal3f( 0.0, 0.0, -1.0 );
glTexCoord2f( 1.0, 0.0 ); glVertex3f( -1.0, -1.0, -1.0 );
glTexCoord2f( 1.0, 1.0 ); glVertex3f( -1.0, 1.0, -1.0 );
glTexCoord2f( 0.0, 1.0 ); glVertex3f( 1.0, 1.0, -1.0 );
glTexCoord2f( 0.0, 0.0 ); glVertex3f( 1.0, -1.0, -1.0 );
glNormal3f( 0.0, 1.0, 0.0 );
glTexCoord2f( 0.0, 1.0 ); glVertex3f( -1.0, 1.0, -1.0 );
glTexCoord2f( 0.0, 0.0 ); glVertex3f( -1.0, 1.0, 1.0 );
glTexCoord2f( 1.0, 0.0 ); glVertex3f( 1.0, 1.0, 1.0 );
glTexCoord2f( 1.0, 1.0 ); glVertex3f( 1.0, 1.0, -1.0 );
glNormal3f( 0.0, -1.0, 0.0 );
glTexCoord2f( 1.0, 1.0 ); glVertex3f( -1.0, -1.0, -1.0 );
glTexCoord2f( 0.0, 1.0 ); glVertex3f( 1.0, -1.0, -1.0 );
glTexCoord2f( 0.0, 0.0 ); glVertex3f( 1.0, -1.0, 1.0 );
glTexCoord2f( 1.0, 0.0 ); glVertex3f( -1.0, -1.0, 1.0 );
glNormal3f( 1.0, 0.0, 0.0 );
glTexCoord2f( 1.0, 0.0 ); glVertex3f( 1.0, -1.0, -1.0 );
glTexCoord2f( 1.0, 1.0 ); glVertex3f( 1.0, 1.0, -1.0 );
glTexCoord2f( 0.0, 1.0 ); glVertex3f( 1.0, 1.0, 1.0 );
glTexCoord2f( 0.0, 0.0 ); glVertex3f( 1.0, -1.0, 1.0 );
glNormal3f( -1.0, 0.0, 0.0 );
glTexCoord2f( 0.0, 0.0 ); glVertex3f( -1.0, -1.0, -1.0 );
glTexCoord2f( 1.0, 0.0 ); glVertex3f( -1.0, -1.0, 1.0 );
glTexCoord2f( 1.0, 1.0 ); glVertex3f( -1.0, 1.0, 1.0 );
glTexCoord2f( 0.0, 1.0 ); glVertex3f( -1.0, 1.0, -1.0 );
glEnd();
xRot += xSpeed;
yRot += ySpeed;
}
void NeHeWidget::initializeGL()
{
loadGLTextures();
glEnable( GL_TEXTURE_2D );
glShadeModel( GL_SMOOTH );
glClearColor( 0.0, 0.0, 0.0, 0.5 );
glClearDepth( 1.0 );
glEnable( GL_DEPTH_TEST );
glDepthFunc( GL_LEQUAL );
glHint( GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST );
glLightfv( GL_LIGHT1, GL_AMBIENT, lightAmbient );
glLightfv( GL_LIGHT1, GL_DIFFUSE, lightDiffuse );
glLightfv( GL_LIGHT1, GL_POSITION, lightPosition );
glEnable( GL_LIGHT1 );
}
void NeHeWidget::resizeGL( int width, int height )
{
if ( height == 0 )
{
height = 1;
}
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() )
{
case Qt::Key_L:
light = !light;
if ( !light )
{
glDisable( GL_LIGHTING );
}
else
{
glEnable( GL_LIGHTING );
}
updateGL();
break;
case Qt::Key_F:
filter += 1;;
if ( filter > 2 )
{
filter = 0;
}
updateGL();
break;
case Qt::Key_PageUp:
zoom -= 0.2;
updateGL();
break;
case Qt::Key_PageDown:
zoom += 0.2;
updateGL();
break;
case Qt::Key_Up:
xSpeed -= 0.01;
updateGL();
break;
case Qt::Key_Down:
xSpeed += 0.01;
updateGL();
break;
case Qt::Key_Right:
ySpeed += 0.01;
updateGL();
break;
case Qt::Key_Left:
ySpeed -= 0.01;
updateGL();
break;
case Qt::Key_F2:
fullscreen = !fullscreen;
if ( fullscreen )
{
showFullScreen();
}
else
{
showNormal();
setGeometry( 100, 100, 640, 480 );
}
update();
break;
case Qt::Key_Escape:
close();
}
}
void NeHeWidget::loadGLTextures()
{
QImage tex, buf;
if ( !buf.load( ":/MyBmp/Crate.bmp" ) )
{
qWarning( "Could not read image file, using single-color instead." );
QImage dummy( 128, 128, /*32*/QImage::Format_Indexed8);
dummy.fill( Qt::green );
buf = dummy;
}
tex = QGLWidget::convertToGLFormat( buf );
glGenTextures( 3, &texture[0] );
glBindTexture( GL_TEXTURE_2D, texture[0] );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
glTexImage2D( GL_TEXTURE_2D, 0, 3, tex.width(), tex.height(), 0,
GL_RGBA, GL_UNSIGNED_BYTE, tex.bits() );
glBindTexture( GL_TEXTURE_2D, texture[1] );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
glTexImage2D( GL_TEXTURE_2D, 0, 3, tex.width(), tex.height(), 0,
GL_RGBA, GL_UNSIGNED_BYTE, tex.bits() );
glBindTexture( GL_TEXTURE_2D, texture[2] );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST );
gluBuild2DMipmaps( GL_TEXTURE_2D, GL_RGB, tex.width(), tex.height(),
GL_RGBA, GL_UNSIGNED_BYTE, tex.bits() );
}
main.cpp文件
/*
Qt OpenGL Tutorial - Lesson 07
main.cpp
v 1.00
2002/12/19
Copyright (C) 2002 Cavendish
cavendish@qiliang.net
http://www.qiliang.net/nehe_qt
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
*/
#include <QtGui/QApplication>
#include <QtGui/QMainWindow>
#include <QtGui/QWidget>
#include <QtGui/QMessageBox>
#include <Qt/qgl.h>
#include "nehewidget.h"
int main( int argc, char **argv )
{
bool fs = false;
QApplication a(argc,argv);
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;
}
NeHeWidget w( 0, 0, fs );
//a.setMainWidget( &w );//QT4.X以上版本不需要了
//a.setActiveWindow( &w );
w.show();
return a.exec();
}
工程的创建方法与前面是一样的
1.用VS2005建立一个空的CONSOLE工程,创建一个.qrc资源文件,里面直接这样写
<RCC>
<qresource prefix="MyBmp" >
<file>Crate.bmp</file>
</qresource>
</RCC>
保存Crate.bmp为图片文件
然后把Crate.bmp,.qrc资源文件,main.cpp,nehewidget.h,nehewidget.cpp,lesson07.cpro,(我改成了
MyOgl.pro)拷贝到你的工程目录下,把.qrc资源文件作为源文件导入你的工程里;
2.然后进入cmd,进入到你的工程目录下,我的为MyOgl,
D:/MyOgl> qmake -project -t vcapp -o MyOgl.pro
D:/MyOgl> qmake
D:/MyOgl> moc.exe nehewidget.h -o debug/moc_nehewidget.cpp
D:/MyOgl> moc.exe nehewidget.h -o release/moc_nehewidget.cpp(也可以直接拷贝debug的)
这个会生成moc_nehewidget.cpp的文件,没有这个运行不了,把与main.cpp放到同一个目录下(没想到Qt
还要对类这样处理,主要是因为nehewidget.h,你的类是Q_OBJECT,比VC麻烦多了)
用新生成生成的.vcproj文件代替原来的,与我的前面两篇文章介绍的方法一样
3.然后打开你的工程
设置“在共享 DLL 中使用 MFC”,“使用多字节字符集”,附加依赖项里面添加上glu32.lib
opengl32.lib
d:/Qt/4.4.3/lib/QtOpenGL.lib(视你的目录而定)
然后就是重新导入main.cpp和nehewidget.cpp文件就OK了,编译吧,与运行后就能看到一个木箱的侧面的
图片了^_^(这个图片在DX的火龙的那本书里也有,呵呵)
本文来自CSDN博客,转自:http://blog.csdn.net/feilinhe/archive/2009/07/24/4377074.aspx