介绍:新入手的项目中,需要使用3维图像进行可视化展示。空间图像由3维坐标轴、立方体、点和2斜切面组成。
1. Qt6.6.0自带的MinGW编译库中包含有OpenGL库文件,路径为:Qt\Tools\mingw1120_64\x86_64-w64-mingw32\include\GL,其中文件组成为:
2. 自定义3维绘图窗口,在QT中使用OpenGL需要继承自QOpenGLWidget,引入glu.h头文件。
#include <GL/glu.h>
3. QOpenGLWidget提供了三个虚函数用以重载来实现OpenGL的绘制,对虚函数进行重载:
1> initializeGL() -- 注册函数:设置GL的渲染绘制属性、定义显示列表、载入固定纹理等初始化工作。在initializeGL()在调用paintGL()之前只被调用一次,之后不再调用。
glClearColor(1.0, 1.0, 1.0, 0.0); // 清空当前的所有颜色
glColor3f(0.0f, 0.0f, 0.0f); // 设置为黑色
glEnable(GL_DEPTH_TEST);
glEnable(GL_POINT_SMOOTH);
glPointSize(8.0);
2> resizeGL() -- 窗体尺寸函数:用于处理当部件大小发生改变时,对OpenGL绘图管线各矩阵需要进行的操作。该函数paintGL()第一次调用之前,initializeGL()调用之后被第一次被调用, 之后每当QGLWidget的不见大小发生改变时,都将调用该函数来对视图、投影矩阵等进行相应的设置。
glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45.0, (float)w/(float)h, 0.1, 100.0);
glMatrixMode(GL_MODELVIEW);
3> paintGL() -- 绘制函数:在此使用OpenGL中的接口进行场景绘制,QGLWidget的paintEvent( QPaintEvent* )将会自动调用 paintGL()进行部件的显示绘制。也可在需要重绘时通过updateGL()时调用paintGL(),和paintEvent使用基本相似。
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
// gluLookAt(0.8, 3.0, 5.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
gluLookAt(0.0, 3.0, 5.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0); // 观看视角
glPushMatrix();
glMultMatrixf(m_transform.constData());
drawImage(); // 自定义绘制动作
glPopMatrix();
4.再drawImage中进行图像的绘制
1> 点的绘制
glClearColor(1.0, 1.0, 1.0, 0.0); // 清空当前的所有颜色
glColor3f(1.0f, 0.0f, 0.0f); // 设置为红色
glBegin(GL_POINTS);
glVertex3f(x, y, z);
glEnd();
2> 线的绘制
glClearColor(1.0, 1.0, 1.0, 0.0); // 清空当前的所有颜色
glColor3f(0.0f, 0.0f, 0.0f); // 设置为黑色
glBegin(GL_LINES);
glVertex3f(0 - X_OFF, 2.0 - i*0.2, 0);
glVertex3f(6 - X_OFF, 2.0 - i*0.2, 0);
glEnd();
3> 面的绘制
glClearColor(1.0, 1.0, 1.0, 0.0); // 清空当前的所有颜色
glColor3f(0.96f, 0.96f, 0.96f); // 设置为灰色
glBegin(GL_POLYGON);
glVertex3f(-X_OFF, 2.0, -0.01);
glVertex3f(X_OFF, 2.0, -0.01);
glVertex3f(X_OFF, -2.0, -0.01);
glVertex3f(-X_OFF, -2.0, -0.01);
glEnd();
4> 简单文字(不包括汉字)的绘制
// 绘制文字接口
void drawstring(const char* str)
{
static int isfirstcall = 1;
static GLuint lists;
if(isfirstcall)
{
isfirstcall = 0;
lists = glGenLists(128);
wglUseFontBitmaps(wglGetCurrentDC(),0,128,lists);
}
for(; *str !='\0'; ++str)
{
glCallList(lists + *str);
}
}
glClearColor(1.0, 1.0, 1.0, 0.0); // 清空当前的所有颜色
glColor3f(0.0f, 0.0f, 0.0f); // 设置为黑色
glRasterPos3f(x, y, z);
drawstring(text.toStdString().c_str());
5> 在Qt中使用QOpenGLWidget绘制中文文字,需要使用到QTextLayout和QFont类。具体步骤如下:
<1>创建一个QTextLayout对象,并设置要绘制的文本。
QTextLayout textLayout;
textLayout.setText(QString("中文"));
<2> 创建一个QFont对象,并设置字体属性。
QFont font;
font.setFamily("Microsoft YaHei");
font.setPointSize(12);
<3> 将QFont对象应用到QTextLayout对象。
textLayout.setFont(font);
<4> 在QOpenGLWidget的paintGL()函数中,使用QOpenGLWidget的renderText()函数绘制文本。
void QOpenGLWidget::paintGL()
{
QPainter painter(this);
painter.beginNativePainting();
renderText(0, 0, textLayout);
painter.endNativePainting();
}
<5> 在QOpenGLWidget的initializeGL()函数中,设置OpenGL的渲染状态。
void QOpenGLWidget::initializeGL()
{
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
}
<6> 在QOpenGLWidget的resizeGL()函数中,设置视口大小。
void QOpenGLWidget::resizeGL(int width, int height)
{
glViewport(0, 0, width, height);
}
这样,就可以在QOpenGLWidget中绘制中文文字了。
6> 立方体绘制
暂时使用六个平面进行包围,伪操作。OpenGL应该有实体绘制的接口。