QOpenGLWidget + QPainter混合程式設計
阿新 • • 發佈:2019-01-29
本示例將一個二維陣列視覺化,且每一個數據點的顏色由它的Z值決定。根據http://blog.csdn.net/dp_huang/article/details/53816805 在呼叫opengl函式時,要使用glEnable(GL_DEPTH_TEST);而使用QPainter之前,要使用glDisable(GL_DEPTH_TEST);
本示例用到了gluLookAt,所以在pro檔案裡要註明 -lGLU32:
#------------------------------------------------- # # Project created by QtCreator 2017-11-07T08:43:48 # #------------------------------------------------- QT += widgets opengl TARGET = wdtJamInfo TEMPLATE = lib DEFINES += WDTJAMINFO_LIBRARY SOURCES += wdtjaminfo.cpp \ IntEdit.cpp \ OperationArray2D.cpp \ wdtjamplot3d.cpp HEADERS += wdtjaminfo.h\ wdtjaminfo_global.h \ IntEdit.h \ OperationArray2D.h \ wdtjamplot3d.h unix { target.path = /usr/lib INSTALLS += target } LIBS += -lopengl32 -lGLU32 FORMS += \ wdtjaminfo.ui
資料從函式OnLoadData出進入,觸發繪製。
#ifndef WDTJAMPLOT3D_H #define WDTJAMPLOT3D_H #include <QOpenGLWidget> #include <QOpenGLFunctions> class wdtJamPlot3D : public QOpenGLWidget, protected QOpenGLFunctions { Q_OBJECT public: explicit wdtJamPlot3D(QWidget *parent = 0); ~wdtJamPlot3D(); GLfloat * m_pVertices; GLfloat * m_pColor; int m_iVertices; int m_iStartFreq; int m_iEndFreq; signals: protected: void initializeGL() Q_DECL_OVERRIDE; void paintGL() Q_DECL_OVERRIDE; void resizeGL(int width, int height) Q_DECL_OVERRIDE; void vDrawAxes(int, int, int); public slots: void OnLoadData(unsigned char *, int iWidth, int iHeight, float fFreqInterval); }; #endif // WDTJAMPLOT3D_H
#include "wdtjamplot3d.h" #include <GL/GLU.h> #include <QPainter> wdtJamPlot3D::wdtJamPlot3D(QWidget *parent) : QOpenGLWidget(parent) { m_pVertices = NULL; m_pColor = NULL; m_iVertices = 0; m_iStartFreq = 8200; m_iEndFreq = 8560; } wdtJamPlot3D::~wdtJamPlot3D() { if(m_pVertices) delete [] m_pVertices; if(m_pColor) delete [] m_pColor; } void wdtJamPlot3D::initializeGL() { initializeOpenGLFunctions(); glEnable(GL_CULL_FACE); } void wdtJamPlot3D::paintGL() { glEnable(GL_DEPTH_TEST); glClearColor(0, 0, 0, 0); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //glColor4f(0,1,0, 0); glPointSize(1.0); glEnableClientState(GL_VERTEX_ARRAY); glEnableClientState(GL_COLOR_ARRAY); glColorPointer(4, GL_FLOAT, 4 * sizeof(GL_FLOAT), m_pColor); glVertexPointer(3, GL_FLOAT, 3 * sizeof(GL_FLOAT), m_pVertices); glDrawArrays(GL_POINTS, 0, m_iVertices); //glDrawArrays(GL_TRIANGLE_FAN, 0, 3); glDisableClientState(GL_VERTEX_ARRAY); glDisableClientState(GL_COLOR_ARRAY); vDrawAxes(360, 360, 256); glDisable(GL_DEPTH_TEST); QPainter qp; qp.begin(this); qp.setPen(QColor(0, 255, 0)); qp.drawText(width()/6, height()/5, QString("255")); qp.drawText(width()/12, height()/5 * 2, QString::fromLocal8Bit("幅度(dB)")); qp.drawText(width()/6, height()/5 * 3, QString("0")); qp.setPen(QColor(255, 255, 0)); qp.drawText(width()/6, height()/5 * 3.5, QString("360")); qp.drawText(width()/9, height()/5 * 4, QString::fromLocal8Bit("方位(度)")); qp.drawText(width()/3.9, height()/5 * 3.8, QString("0")); qp.setPen(QColor(255, 255, 255)); qp.drawText(width()/2.8, height()/5 * 4, QString().setNum(m_iStartFreq)); qp.drawText(width()/2, height()/5 * 4, QString::fromLocal8Bit("頻率(MHz)")); qp.drawText(width()/3 * 2.4, height()/5 * 4, QString().setNum(m_iEndFreq)); qp.end(); } void wdtJamPlot3D::resizeGL(int width, int height) { int side = qMin(width, height); glViewport((width - side) / 2, (height - side) / 2, side, side); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrtho(-400,400, -400,400, 10, 500); glMatrixMode(GL_MODELVIEW); gluLookAt(100, -100, 200, 180,180,128, 0,0,1); } void wdtJamPlot3D::OnLoadData(unsigned char *pData, int iWidth, int iHeight, float fFreqInterval) { if(m_pVertices) delete [] m_pVertices; if(m_pColor) delete [] m_pColor; m_iVertices = iWidth * iHeight; m_pVertices = new GLfloat[m_iVertices * 3]; m_pColor = new GLfloat[m_iVertices * 4]; for(int x = 0; x < iWidth; x++) { for(int y = 0; y < iHeight; y++) { GLfloat fZ = pData[y * iWidth + x]; m_pVertices[iWidth * y * 3 + x * 3] = 360.0 * x / iWidth; m_pVertices[iWidth * y * 3 + x * 3 + 1] = 360.0 * y / iHeight; m_pVertices[iWidth * y * 3 + x * 3 + 2] = fZ * 1.5; m_pColor[iWidth * y * 4 + x * 4] = (255 - fZ)/255.0; m_pColor[iWidth * y * 4 + x * 4 + 1] = 0; m_pColor[iWidth * y * 4 + x * 4 + 2] = fZ/255.0; m_pColor[iWidth * y * 4 + x * 4 + 3] = 0; } } m_iStartFreq = 8200; m_iEndFreq = m_iStartFreq + fFreqInterval * (iWidth - 1); update(); } void wdtJamPlot3D::vDrawAxes(int iFreqLength, int iAngleLength, int iAmpLength) { //GLfloat arrPnts[18] = {0, 0, 0, 360, 0, 0, 0, 0, 0, 0, 360, 0, 0, 360, 0, 0, 360, 256}; glPointSize(3.0); // glEnableClientState(GL_VERTEX_ARRAY); // glEnableClientState(GL_COLOR_ARRAY); // glVertexPointer(3, GL_FLOAT, 3 * sizeof(GL_FLOAT), arrPnts); // glDrawArrays(GL_LINE, 0, 2); // glDrawArrays(GL_LINE, 6, 2); // glDrawArrays(GL_LINE, 12, 2); // // glDisableClientState(GL_VERTEX_ARRAY); // glDisableClientState(GL_COLOR_ARRAY); glBegin(GL_LINES); glColor4f(1.0, 1.0, 1.0, 0); glVertex3f(0,0,0); glVertex3f(360, 0, 0); glColor4f(1.0, 1.0, 0.0, 0); glVertex3f(0,0,0); glVertex3f(0, 360, 0); glColor4f(0.0, 1.0, 0.0, 0); glVertex3f(0,360,384); glVertex3f(0, 360, 0); glEnd(); }
效果: