Qt OpenGL
模块可以很方便地将OpenGL应用在Qt程序中,本文使用其画了一个3D坐标轴(见上图),并详细讲解了具体的编码过程与官方手册的使用。
OpenGL
是业界采用最广泛的二维和三维图形API。它独立于窗口系统和操作系统,并且网络透明。OpenGL使软件开发人员能够在CAD、内容创建、能源、娱乐、游戏开发、制造、医疗和虚拟现实等市场中创建高性能、视觉吸引力强的图形软件应用程序。但是OpenGL
只处理3D渲染,对于GUI编程并不友好。OpenGL应用程序的用户界面必须使用另一个工具包创建,比如MFC或Qt
。
QT += opengl
win32:LIBS += -lOpengl32 -lglu32
unix:LIBS += -lglut -lGLU
class QopenGLDemo : public QOpenGLWidget
QopenGLDemo *m_gl = new QopenGLDemo(this);
this->setCentralWidget(m_gl);
initializeGL
、resizeGL
、paintGL
,后续有三个函数的完整代码核心为paintGL
函数的实现
// 初始化
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //清除屏幕和深度缓存
glLoadIdentity(); // 重置
glTranslatef(0, 0, -30); // 调整绘图坐标
// 坐标轴
float axis_length = 10;
glLineWidth(5);
glBegin(GL_LINE_STRIP);
glColor3f(1, 0, 0);
glVertex3f(0, 0, 0);
glVertex3f(axis_length, 0, 0);
glEnd();
glFlush();
glBegin(GL_LINE_STRIP);
glColor3f(0, 1, 0);
glVertex3f(0, 0, 0);
glVertex3f(0, axis_length, 0);
glEnd();
glFlush();
glBegin(GL_LINE_STRIP);
glColor3f(0, 0, 1);
glVertex3f(0, 0, 0);
glVertex3f(0, 0, axis_length);
glEnd();
glFlush();
glTranslatef(0, 0, -30);
一定要有,根据投影矩阵:绘制的图形的Z轴坐标 >=0的话屏幕就不会显示。上图由于角度问题,并没有显示z轴…
glTranslatef(0, 0, -30); // 调整绘图坐标
glRotatef(45.0, 0, -1, 0); // 绕y轴旋转45度
glRotatef(45.0, 1, 0, -1); // 绕向量(1,0,-1) 旋转45度
增加两行旋转代码,感觉有那么点立体的意思了
// 坐标轴箭头 参考官方文档: https://registry.khronos.org/OpenGL-Refpages/gl4/
GLUquadricObj *objCylinder = gluNewQuadric();
glPushMatrix();
glColor3f(0, 0, 1);
glTranslatef(0, 0, axis_length);
gluCylinder(objCylinder, 0.3, 0.0, 0.3, 100, 1); // gluCylinder绘制一个沿z轴定向的圆柱体
glPopMatrix();
glPushMatrix();
glColor3f(1, 0, 0);
glRotatef(90, 0, 1, 0); // 沿着y轴转90度 使得x轴对着原z轴方向
glTranslatef(0, 0, axis_length);
gluCylinder(objCylinder, 0.3, 0.0, 0.3, 100, 1); // gluCylinder绘制一个沿z轴定向的圆柱体
glPopMatrix();
glPushMatrix();
glColor3f(0, 1, 0);
glRotatef(-90, 1, 0, 0.0); // 沿着x轴转90度 使得y轴对着原z轴方向
glTranslatef(0, 0, axis_length);
gluCylinder(objCylinder, 0.3, 0.0, 0.3, 100, 1); // gluCylinder绘制一个沿z轴定向的圆柱体
glPopMatrix();
由于gluCylinder
这个函数只能在原点处冲着z轴正向画圆柱(锥),想要在x轴和y轴上画,需要先将这两个轴旋转到z轴位置,并且进行平移。其中glPushMatrix
即保存现场,直接glPopMatrix
就会使得原点回到旋转和平移之前的位置。
// 画原点 - 白色
glPointSize(10.0f);
glBegin(GL_POINTS);
glColor3f(1, 1, 1);
glVertex3f(0, 0, 0);
glEnd();
glFlush();
void QopenGLDemo::initializeGL(){
glClearColor(0.0f, 0.0f, 0.0f, 1.0f); // rgba
glShadeModel(GL_SMOOTH); // 平滑着色 GL_FLAT 单调着色
}
void QopenGLDemo::resizeGL(int w, int h){
glViewport(0, 0, w, h); //重置当前的视口
// glMatrixMode() 用以指定当前要操作的矩阵 GL_MODELVIEW(模型视图,默认值),GL_PROJECTION(投影),GL_TEXTURE(纹理),GL_COLOR(颜色)
glMatrixMode(GL_PROJECTION); //选择投影矩阵
glLoadIdentity(); //重置投影矩阵 为 单位矩阵
gluPerspective(60.0, double(w) / h, 0.1, 1000.0); //建立透视投影
glMatrixMode(GL_MODELVIEW); //选择模型矩阵
glLoadIdentity(); //重置模型矩阵 为 单位矩阵
}
void QopenGLDemo::paintGL(){
// 初始化
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //清除屏幕和深度缓存
glLoadIdentity(); // 重置
glTranslatef(0, 0, -30); // 调整绘图坐标
glRotatef(45.0, 0, -1, 0); // 绕y轴旋转45度
glRotatef(45.0, 1, 0, -1); // 绕向量(1,0,-1) 旋转45度
// 坐标轴
float axis_length = 10;
glLineWidth(5);
glBegin(GL_LINE_STRIP);
glColor3f(1, 0, 0);
glVertex3f(0, 0, 0);
glVertex3f(axis_length, 0, 0);
glEnd();
glFlush();
glBegin(GL_LINE_STRIP);
glColor3f(0, 1, 0);
glVertex3f(0, 0, 0);
glVertex3f(0, axis_length, 0);
glEnd();
glFlush();
glBegin(GL_LINE_STRIP);
glColor3f(0, 0, 1);
glVertex3f(0, 0, 0);
glVertex3f(0, 0, axis_length);
glEnd();
glFlush();
// 坐标轴箭头 参考官方文档: https://registry.khronos.org/OpenGL-Refpages/gl4/
GLUquadricObj *objCylinder = gluNewQuadric();
glPushMatrix();
glColor3f(0, 0, 1);
glTranslatef(0, 0, axis_length);
gluCylinder(objCylinder, 0.3, 0.0, 0.3, 100, 1); // gluCylinder绘制一个沿z轴定向的圆柱体
glPopMatrix();
glPushMatrix();
glColor3f(1, 0, 0);
glRotatef(90, 0, 1, 0); // 沿着y轴转90度 使得x轴对着原z轴方向
glTranslatef(0, 0, axis_length);
gluCylinder(objCylinder, 0.3, 0.0, 0.3, 100, 1); // gluCylinder绘制一个沿z轴定向的圆柱体
glPopMatrix();
glPushMatrix();
glColor3f(0, 1, 0);
glRotatef(-90, 1, 0, 0.0); // 沿着x轴转90度 使得y轴对着原z轴方向
glTranslatef(0, 0, axis_length);
gluCylinder(objCylinder, 0.3, 0.0, 0.3, 100, 1); // gluCylinder绘制一个沿z轴定向的圆柱体
glPopMatrix();
// 画原点 - 白色
glPointSize(10.0f);
glBegin(GL_POINTS);
glColor3f(1, 1, 1);
glVertex3f(0, 0, 0);
glEnd();
glFlush();
}
官网:https://www.opengl.org/
官方手册(进官网点 Documentation
),如下图:
官方手册好像是没有搜索功能的…
以OpenGL 4 Reference Pages
中的gluCylinder函数
为例:https://registry.khronos.org/OpenGL-Refpages/gl4/
OpenGL 4 Reference Pages
手册地址,glu
开头的函数点击下图箭头处链接:gluCylinder函数
点击即可看到其具体的参数: