1 Star 0 Fork 0

陈天灿/musicPlayer

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
cdplayer.cpp 13.92 KB
一键复制 编辑 原始数据 按行查看 历史
#include "head.h"
//class CdPlayer:public QWidget
//{
// Q_OBJECT
//public:
// CdPlayer();
// ~CdPlayer();
//public:
// constexpr static double pi = 3.1415926;
//private slots:
// //参数是一个进度占比
// void acceptMusicProgress(double rotia);
// void acceptStart();
//signals:
// //参数是一个进度占比
// void musicProgress(double rotia);
//private:
// void paintEvent(QPaintEvent *event) override;
// void mousePressEvent(QMouseEvent *event) override;
// void mouseMoveEvent(QMouseEvent *event) override;
// void mouseReleaseEvent(QMouseEvent *event) override;
//private:
// QPoint _centralPoint;//cd中心点
// QPoint _centralRoundRadius;//圆半径
// QPoint _cdArmPos;//cd的机器臂位置
// QPoint _squareA;
// QPoint _squareB;
// QPoint _squareC;
// QPoint _squareD;
// double _orginalRotationAngle;
// double _currentRotationAngle;
// double _maxRotationAngle;
//};
CdPlayer::CdPlayer(QOpenGLWidget *parent)
:QOpenGLWidget(parent)
{
//设置最小值在使用布局管理器时很有必要。布局管理器的自动分配大小可能会是均匀分配
setMinimumSize(Widget::MAINWIDGET_WIDTH, Height);
resize(Widget::MAINWIDGET_WIDTH, Height);
// QSurfaceFormat format;
// format.setAlphaBufferSize(8); // 设置alpha缓冲区大小为8位
// setFormat(format);
setAttribute(Qt::WA_TranslucentBackground, true);
setAttribute(Qt::WA_AlwaysStackOnTop);
_picture = QImage(":/images/Resources/cdBackground.png");
_picture2 = QImage(":/images/Resources/cdPlayJoystick.png");
// _centralPoint = QPoint(width()/2, 426 - 25)
// setStyleSheet("QLabel {background-color: white;}");//设置样式
// setAutoFillBackground(true);//执行填充
}
void CdPlayer::initPoint(QPoint centralPoint, QPoint cdArmPos)
{
_centralPoint = QPoint(width()/2, 326 - centralPoint.y());
_cdArmPos = cdArmPos;
_maxRotationAngle = 20;
_isOrNoInRectArea = false;
_centralRoundRadius = 325 - _centralPoint.x();
_lengthA = 357.00;
_lenthC = 318.00;
_lenthB = 370.00;
_lenthD = 302.00;
// _curLengthA = _lengthA;
// _curLenthB = _lenthB;
// _curLenthC = _lenthC;
// _curLenthD = _lenthD;
_squareA = MyPoint(_cdArmPos.rx() - qSin(_angleAOrg) * _lengthA, _cdArmPos.y() + qCos(_angleAOrg)*_lengthA);
_squareB = MyPoint(_cdArmPos.rx() - qSin(_angleBOrg) * _lenthB, _cdArmPos.y() + qCos(_angleBOrg)*_lenthB);
_squareC = MyPoint(_cdArmPos.rx() - qSin(_angleCOrg) * _lenthC, _cdArmPos.y() + qCos(_angleCOrg)*_lenthC);
_squareD = MyPoint(_cdArmPos.rx() - qSin(_angleDOrg) * _lenthD, _cdArmPos.y() + qCos(_angleDOrg)*_lenthD);
_squareCurA = _squareA;
_squareCurB = _squareB;
_squareCurC = _squareC;
_squareCurD = _squareD;
_angleAMax = _maxRotationAngle*pi/180 + _angleAOrg;
_angleBMax = _maxRotationAngle*pi/180 + _angleBOrg;
_angleCMax = _maxRotationAngle*pi/180 + _angleCOrg;
_angleDMax = _maxRotationAngle*pi/180 + _angleDOrg;
_squareMaxA = MyPoint(_cdArmPos.rx() - qSin(_angleAMax) * _lengthA, _cdArmPos.y()
+ qCos(_angleAMax)*_lengthA);
_squareMaxB = MyPoint(_cdArmPos.rx() - qSin(_angleBMax) * _lenthB,
_cdArmPos.y() + qCos(_angleBMax)*_lenthB);
_squareMaxC = MyPoint(_cdArmPos.rx() - qSin(_angleCMax) * _lenthC,
_cdArmPos.y() + qCos(_angleCMax)*_lenthC);
_squareMaxD = MyPoint(_cdArmPos.rx() - qSin(_angleDMax) * _lenthD,
_cdArmPos.y() + qCos(_angleDMax)*_lenthD);
_cdAngleMax = 360;
_cdAngleMin = 0;
}
CdPlayer::~CdPlayer()
{
glDeleteTextures(1, &_cdTex);
glDeleteTextures(1, &_armTex);
}
void CdPlayer::acceptResetBegin()
{
resetMin();
update();
}
void CdPlayer::acceptStart()
{
}
void CdPlayer::acceptMusicProgress(double rotia)
{
auto increase = rotia * _maxRotationAngle - _currentRotationAngle;
auto radian = increase * pi/180;
updateCurrentPoint(radian);
update();
}
//检验是否在长方形内部
bool CdPlayer::locateSqureAreaInternal(QPoint p)
{
auto PA = MyPoint(p) - _squareCurA;
auto PB = MyPoint(p) - _squareCurB;
auto PC = MyPoint(p) - _squareCurC;
auto PD = MyPoint(p) - _squareCurD;
auto PAPB = PA.x()*PB.y() - PA.y()*PB.x();
auto PBPC = PB.x()*PC.y() - PB.y()*PC.x();
auto PCPD = PC.x()*PD.y() - PC.y()*PD.x();
auto PDPA = PD.x()*PA.y() - PD.y()*PA.x();
if((PAPB > 0 && PBPC >0 && PCPD >0 && PDPA > 0) || (PAPB < 0 && PBPC < 0 && PCPD < 0 && PDPA < 0))
{
return true;
}else{
return false;
}
}
double getVecValue(const MyPoint &vec)
{
return qSqrt((vec.x()*vec.x() + vec.y() * vec.y()));
}
//获取向量夹角,单位弧度
double CdPlayer::GetAngle(const QPoint &vec1, const QPoint & vec2)
{
auto vec1Sqrt = qSqrt((vec1.x()*vec1.x() + vec1.y() * vec1.y()));
auto vec2Sqrt = qSqrt((vec2.x()*vec2.x() + vec2.y() * vec2.y()));
auto vec1vec2 = vec1.x()*vec2.x() + vec1.y()*vec2.y();
auto cosValue = vec1vec2 / (vec1Sqrt * vec2Sqrt);
auto diffRadian = qAcos(cosValue);
return diffRadian;
}
double CdPlayer::GetAngle(const MyPoint &vec1, const MyPoint & vec2)
{
auto vec1Sqrt = qSqrt((vec1.x()*vec1.x() + vec1.y() * vec1.y()));
auto vec2Sqrt = qSqrt((vec2.x()*vec2.x() + vec2.y() * vec2.y()));
auto vec1vec2 = vec1.x()*vec2.x() + vec1.y()*vec2.y();
auto cosValue = vec1vec2 / (vec1Sqrt * vec2Sqrt);
auto diffRadian = qAcos(cosValue);
return diffRadian;
}
//出现bug第一时间先查看有没有不小心错漏的(比如应该写加号,结果是减号)
void CdPlayer::updateRadian()
{
_squareCurA = MyPoint(_cdArmPos.rx() - qSin(_angleACur) * _lengthA, _cdArmPos.y() + qCos(_angleACur)*_lengthA);
_squareCurB = MyPoint(_cdArmPos.rx() - qSin(_angleBCur) * _lenthB, _cdArmPos.y() + qCos(_angleBCur)*_lenthB);
_squareCurC = MyPoint(_cdArmPos.rx() - qSin(_angleCCur) * _lenthC, _cdArmPos.y() + qCos(_angleCCur)*_lenthC);
_squareCurD = MyPoint(_cdArmPos.rx() - qSin(_angleDCur) * _lenthD, _cdArmPos.y() + qCos(_angleDCur)*_lenthD);
}
void CdPlayer::updateCurrentPoint(double RadianAdded)
{
_angleACur += RadianAdded;
_angleBCur += RadianAdded;
_angleCCur += RadianAdded;
_angleDCur += RadianAdded;
_currentRotationAngle += RadianAdded*180.0 / pi;
_cdAngleCur = _currentRotationAngle/_maxRotationAngle * _cdAngleMax;
// emit sendMusicProgress(_currentRotationAngle/_maxRotationAngle);
updateRadian();
}
//叉乘
int CdPlayer::CrossProduct(const QPoint &vec1, const QPoint &vec2)
{
return (vec1.x()*vec2.y() - vec1.y()*vec2.x());
}
//用于判断旋转方向,一个是当前鼠标坐标,一个是先前的鼠标坐标.正数是顺时针, 0是不动,负数是逆时针
int CdPlayer::AdvanceOrRetreat(const QPoint &dotCur, const QPoint &dot2Last)
{
auto lastO = _cdArmPos - dot2Last;
auto curO = dotCur - dot2Last;
auto r = CrossProduct(lastO, curO);
return r;
}
void CdPlayer::resetMin()
{
_squareCurA = _squareA;
_squareCurB = _squareB;
_squareCurC = _squareC;
_squareCurD = _squareD;
_angleACur = _angleAOrg;
_angleBCur = _angleBOrg;
_angleCCur = _angleCOrg;
_angleDCur = _angleDOrg;
_currentRotationAngle = 0.00;
_cdAngleCur = _cdAngleMin;
emit sendMusicProgress(0);
emit sendVlcProgress(0);
}
void CdPlayer::resetMax()
{
_squareCurA = _squareMaxA;
_squareCurB = _squareMaxB;
_squareCurC = _squareMaxC;
_squareCurD = _squareMaxD;
_angleACur = _angleAMax;
_angleBCur = _angleBMax;
_angleCCur = _angleCMax;
_angleDCur = _angleDMax;
_currentRotationAngle = _maxRotationAngle;
_cdAngleCur = _cdAngleMax;
emit sendMusicProgress(1);
emit sendVlcProgress(1);
}
//mousePress与mouseMove两者是独立的,不像dragEnterEvent和dropEvent
void CdPlayer::mousePressEvent(QMouseEvent *event)
{
if(event->button() == Qt::LeftButton)
{
if(locateSqureAreaInternal(event->pos()))
{
// event->accept();
_lastMousePos = event->pos();
_isOrNoInRectArea = true;
}else{
_isOrNoInRectArea = false;
}
}
}
void CdPlayer::mouseMoveEvent(QMouseEvent *event)
{
if((event->buttons() & Qt::LeftButton) && _isOrNoInRectArea)
{
auto diff1 = _lastMousePos - _cdArmPos;
auto diff2 = event->pos() - _cdArmPos;
auto radianAdded = GetAngle(diff1, diff2);
// decltype (radianAdded) RadianAdded = 0;
//向量叉乘判断旋转方向
auto res = AdvanceOrRetreat(event->pos(), _lastMousePos);
// qDebug() << radianAdded << "000";
if(res < 0)
{
updateCurrentPoint(radianAdded);
// RadianAdded = radianAdded;
}else{
updateCurrentPoint(-radianAdded);
// RadianAdded = -radianAdded;
}
_lastMousePos = event->pos();
// _currentMinDistance = qSin(GetAngle(_squareCurD - _squareCurA, MyPoint::ToMyPoint(_centralPoint) - _squareCurA))
// * getVecValue(MyPoint::ToMyPoint(_centralPoint) - _squareCurA);
if(/*_currentMinDistance < _centralRoundRadius*/ _currentRotationAngle >= _maxRotationAngle || _currentRotationAngle <= 0)
{
if(_currentRotationAngle <= 0)
{
// qDebug() << _currentRotationAngle*pi/180.0 << "000";
resetMin();
update();
}else{
resetMax();
update();
}
}else{
update();
}
{
emit sendMusicProgress(_currentRotationAngle/_maxRotationAngle);
emit sendVlcProgress(_currentRotationAngle/_maxRotationAngle);
}
}
}
void CdPlayer::errPrint(QString InforMation)
{
decltype(glGetError()) err;
err = glGetError();
while (err != GL_NO_ERROR)
{
// auto string = gluErrorUnicodeStringEXT(GL_OUT_OF_MEMORY);
// size_t lenU8 = WideCharToMultiByte(CP_ACP, 0, string, -1, nullptr, 0, nullptr, nullptr);
// std::unique_ptr<char> u8str(new char[lenU8]());
// WideCharToMultiByte(CP_ACP, 0, string, -1, u8str.get(), lenU8, nullptr, nullptr);
qDebug()
<< "exit err! arr is " << err << InforMation;
err = glGetError();
}
}
void CdPlayer::mouseReleaseEvent(QMouseEvent *event)
{
}
void CdPlayer::paintGL()
{
//未播放音乐前,如果频繁移动机械臂会导致图像消失,目前发现是下面两行代码的问题
// glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
// glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0, width(), height(), 0, 0.1, 1000);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
CCVert cd[] ={
{-211, -211, 0, 0, 1},
{-211, 211, 0, 0,0},
{211, 211, 0, 1, 0},
{211, -211, 0, 1,1}
};
glTranslatef(_centralPoint.x(), _centralPoint.y(), -3);
glRotatef(_cdAngleCur * 200, 0, 0, 1);
glBindTexture(GL_TEXTURE_2D, _cdTex);
glVertexPointer(3, GL_FLOAT, sizeof (CCVert), cd);
glTexCoordPointer(2, GL_FLOAT, sizeof (CCVert), &cd[0].u);
glDrawArrays(GL_QUADS, 0, 4);
glLoadIdentity();
CCVert arm[] = {
{-123, -48, 0, 0, 0},
{-123, 417 - 48, 0, 0,1},
{211 - 123, 417 - 48, 0, 1, 1},
{211 - 123, -48 , 0, 1,0}
};
// glTranslatef(0,0,-3);
glTranslatef(_cdArmPos.x(), _cdArmPos.y(), -3);//指令逆序执行
glRotatef(_currentRotationAngle, 0, 0, 1);
glBindTexture(GL_TEXTURE_2D, _armTex);
glVertexPointer(3, GL_FLOAT, sizeof (CCVert), arm);
glTexCoordPointer(2, GL_FLOAT, sizeof (CCVert), &arm[0].u);
glDrawArrays(GL_QUADS, 0, 4);
errPrint("paintGL");
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
}
void CdPlayer::initializeGL()
{
initializeOpenGLFunctions();
glClearColor(0,0,0,0);
glClearDepth(1);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
glEnable(GL_TEXTURE_2D);
// glEnable(GL_ALPHA_TEST);
// glAlphaFunc(GL_GEQUAL, 1.0f);
glEnable(GL_BLEND);//让图片背景透明,这个项目同等性能下启用混合比启用透明度测试,画质效果要好很多,gpu消耗略微上调一点。
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glGenTextures(1, &_cdTex);
glBindTexture(GL_TEXTURE_2D, _cdTex);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, _picture.width(), _picture.height(), 0, GL_BGRA, GL_UNSIGNED_BYTE, _picture.bits());
glGenTextures(1, &_armTex);
glBindTexture(GL_TEXTURE_2D, _armTex);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, _picture2.width(), _picture2.height(), 0, GL_BGRA, GL_UNSIGNED_BYTE, _picture2.bits());
glBindTexture(1, 0);
}
void CdPlayer::resizeGL(int w, int h)
{
glViewport(0,0,w,h);
}
//void CdPlayer::paintEvent(QPaintEvent *event)
//{
// Q_UNUSED(event)
// QPainter paint(this);
// paint.setRenderHints(QPainter::Antialiasing|QPainter::SmoothPixmapTransform, true);
// paint.save();
// QPixmap picture(":/images/Resources/cdBackground.png");
// paint.translate(QPoint(_centralPoint));
// paint.rotate(_cdAngleCur * 200);
// paint.drawPixmap(QRect(-211,-211, 422, 422), picture, picture.rect());
// paint.restore();
// paint.save();
// QPixmap picture2(":/images/Resources/cdPlayJoystick.png");
// paint.translate(QPoint(_cdArmPos));
// paint.rotate(_currentRotationAngle/*20*/);
// // qDebug() << _currentRotationAngle << "paint";
// paint.drawPixmap(QRect(-123,-48,211,417), picture2, picture2.rect());
// paint.restore();
//}
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
C++
1
https://gitee.com/chen_tiancan/music-player.git
git@gitee.com:chen_tiancan/music-player.git
chen_tiancan
music-player
musicPlayer
master

搜索帮助