简单的一个绘制连续曲线的demo,支持平移,滚轮缩放,没有刻度,不够平滑[可能需要自己写算法],调用这个类就可以,具体的业务需要自己去根据需要更改,比如设置曲线的颜色,设置曲线的x轴的点的个数,自己绘制xy轴的刻度 。
#ifndef OPENGLSHOW_H
#define OPENGLSHOW_H
#include <QObject>
#include <QWidget>
#include <GL/gl.h>
#include <GL/glu.h>
#include <QOpenGLWidget>
#include <QOpenGLFunctions>
#include <QOpenGLVertexArrayObject>
#include <QOpenGLShaderProgram>
#include <QOpenGLBuffer>
#include <QOpenGLVertexArrayObject>
#include <QMouseEvent>
#include <gl/GLU.h>
#include <GL/glaux.h>
#include <GL/glext.h>
#include <GL/wglext.h>
#include <qopengl.h>
#include <QVector>
#include <QPointF>
#include <QMouseEvent>
class openglshow:public QOpenGLWidget,protected QOpenGLFunctions
{
Q_OBJECT
public:
explicit openglshow(QWidget *parent = nullptr);
~openglshow();
void mousePressEvent(QMouseEvent *event);
void mouseReleaseEvent(QMouseEvent *event);
void mouseMoveEvent(QMouseEvent *event);
void wheelEvent(QWheelEvent *event);
public:
void initializeGL() Q_DECL_OVERRIDE;
void paintGL() Q_DECL_OVERRIDE;
void resizeGL(int width,int height) Q_DECL_OVERRIDE;
public:
QVector<qreal>m_testPoint;
bool m_bClicked = false;
QPoint pLast;
QPoint m_MovePoint;
qreal m_Fzoom = 0.0;
bool m_bWheel = false;
QPoint m_Point;
signals:
public slots:
};
#endif // OPENGLSHOW_H
#include "openglshow.h"
#include <QOpenGLBuffer>
#include <QVector2D>
#include <QtMath>
openglshow::openglshow(QWidget *parent) : QOpenGLWidget(parent)
{
m_testPoint.clear();
for(int i = 0;i < 913;i++)
{
qreal ptemp_value = qrand() % 578;
//qDebug()<<"ptemp_valuey="<<ptemp_value;
m_testPoint.append(ptemp_value);
}
}
openglshow::~openglshow()
{
}
void openglshow::initializeGL()
{
#if 0
initializeOpenGLFunctions();
glClearColor(0,0,0,1);
glEnable(GL_DEPTH_TEST);
glEnable(GL_LIGHT0);
glEnable(GL_LIGHTING);
glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);
glEnable(GL_COLOR_MATERIAL);
#else
{
initializeOpenGLFunctions(); //这个是qt使用opengl方法接口
QOpenGLFunctions *f = QOpenGLContext::currentContext()->functions();
f->glClearColor(1.0f, 1.0f, 1.0f, 1.0f); //设置窗体背景色
int w = this->width();
int h = this->height();
glOrtho(0.0,w,h,0.0,-1.0,1.0); //这个代表截取屏幕,这里我这里截取整个屏幕
}
#endif
}
void openglshow::paintGL()
{
#if 0
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLineWidth(1); // 宽度
//glLineColor(r, g, b, a) ; // 颜色
glColor3f(1, 1 , 0);
glBegin(GL_LINES);
//glVertex2f(2, 60); // 第一条线段点B
//glVertex2f(3, 100); // 第二条线段点A
//glVertex2f(4, 200); // 第二条线段点B
for(int i = 0;i< 600;i++)
{
glVertex2f(i+1, i+1); // 第一条线段点A
}
//glDrawPrimitive(GL_LINES); // 绘制线段图元
glEnd();
#else
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glClearColor(1.0f, 1.0f, 1.0f, 1.0f);//修改背景颜色
glColor3f(0.0, 1.0,0.0);
//glBegin(GL_POINTS); //画点
for(int i = 0;i < 60;i++) //这里我是画了100万条线。速度大概1秒左右
{
glLineWidth(1);
#if 0
glBegin(GL_LINES); //画线,不够平滑,抗锯齿
#else
//抗锯齿,平滑点
glEnable( GL_LINE_SMOOTH );
glEnable( GL_POLYGON_SMOOTH );
glHint( GL_LINE_SMOOTH_HINT, GL_NICEST );
glHint( GL_POLYGON_SMOOTH_HINT, GL_NICEST );
glBegin( GL_LINE_STRIP );
#endif
glVertex2f(i * 15,m_testPoint.at(i)); //开始点(x,y)
if(i == 912)
{
glEnd();
return;
}
glVertex2f((i + 1) * 15,m_testPoint.at(i + 1)); //结束点 (x,y) 913,578
glEnd();
}
//平移
if(m_bClicked)
{
glTranslatef(-pLast.x()+m_MovePoint.x(),-pLast.y() + m_MovePoint.y(),0);
pLast = m_MovePoint;
}
//缩放
if(m_bWheel)
{
//进行平移,如果不需要局部则把平移部分去掉。
glTranslatef(m_Point.x()*(1-m_Fzoom),m_Point.y()*(1-m_Fzoom),0);
glScalef(m_Fzoom, m_Fzoom, 0.0);
}
m_Fzoom=1;
m_bWheel=false;
#endif
}
void openglshow::resizeGL(int width,int height)
{
#if 0
glViewport(0,0,width,height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(-width/2,width/2,-height/2,height/2,-1,1);//中间为原点
glMatrixMode(GL_MODELVIEW);
#else
glViewport(0,0,width,height);
qDebug()<<"width="<<width<<"height="<<height;
#endif
}
void openglshow::mousePressEvent(QMouseEvent *event)
{
if(event->button()==Qt::LeftButton)
{
m_bClicked=true;
pLast = event->globalPos() - this->pos(); //点击之后获取当前位置(记录当前点)
}
}
void openglshow::mouseReleaseEvent(QMouseEvent *event)
{
m_bClicked=false;
}
void openglshow::mouseMoveEvent(QMouseEvent *event)
{
if (event->buttons() && Qt::LeftButton&&m_bClicked)
{
m_MovePoint=event->globalPos();
qDebug()<<"m_MovePoint::"<<m_MovePoint<<"pLast::"<<pLast;
glFlush(); //刷新界面 理论上应该这个就会执行paintGL,但是不行,还需要update一下
update();
}
}
//滚动鼠标放大与缩小
void openglshow::wheelEvent(QWheelEvent *event)
{
m_Point= event->globalPos(); //获取当前位置,注意所有的坐标都是相对于桌面的坐标
m_Fzoom=1; //设置默认缩放比例 opengl有一个毛病,就是他认为只有比初始值大为放大
//比初始值小为缩小,所以每次都设置一次初值
m_bWheel=true;
qDebug()<<"point:"<<m_Point;
if(event->delta() > 0) {
m_Fzoom += 0.1; //滚轮 向上
} else {
m_Fzoom -= 0.1;
}
glFlush();
update();
}