主要利用GLSL中的内置变量gl_FrontFacing区分正反面。下面是正面反面效果图:
头文件:
class QOpenGLShaderProgram; class QOpenGLTexture; //--------------------------------------------------------------------------------------- // 显示图片 //--------------------------------------------------------------------------------------- class MzOpenGLWidget : public QOpenGLWidget, private QOpenGLFunctions { Q_OBJECT Q_PROPERTY(float rotate READ rotate WRITE setRotate) public: MzOpenGLWidget(QWidget* parent = 0); ~MzOpenGLWidget(); float rotate() const; void setRotate(float value); private: void initializeGL() override; void paintGL() override; void resizeGL(int w, int h) override; float calcRawRatio(); private: QOpenGLShaderProgram* program; QOpenGLTexture *textureFr; QOpenGLTexture *textureBk; float angle; };
CPP文件:
MzOpenGLWidget::MzOpenGLWidget(QWidget* parent) : QOpenGLWidget(parent), angle(0) { QPropertyAnimation* ani = new QPropertyAnimation(this, "rotate", this); ani->setStartValue(0.0); ani->setEndValue(360.0); ani->setLoopCount(-1); ani->setDuration(4000); ani->start(QAbstractAnimation::DeleteWhenStopped); } MzOpenGLWidget::~MzOpenGLWidget() { delete textureFr; delete textureBk; } void MzOpenGLWidget::initializeGL() { initializeOpenGLFunctions(); glEnable(GL_DEPTH_TEST); glClearColor(0.1, 0.1, 0.1, 1.0); program = new QOpenGLShaderProgram(this); const char* vsrc = R"( in vec4 pos; in vec2 itextCoor; varying vec2 otextCoor; uniform mat4 trans; void main() { gl_Position = trans * pos; otextCoor = itextCoor; })"; program->addShaderFromSourceCode(QOpenGLShader::Vertex, vsrc); const char* fsrc = R"( uniform sampler2D imageFr; uniform sampler2D imageBk; varying vec2 otextCoor; void main() { gl_FragColor = gl_FrontFacing ? texture2D(imageFr, otextCoor) : texture2D(imageBk, otextCoor); })"; program->addShaderFromSourceCode(QOpenGLShader::Fragment, fsrc); QImage frImage(240, 240, QImage::Format_RGB888); frImage.fill(Qt::red); textureFr = new QOpenGLTexture(frImage); textureFr->setMinificationFilter(QOpenGLTexture::Linear); /* 缩小图片插值方法 */ textureFr->setMagnificationFilter(QOpenGLTexture::Nearest); /* 放大图片插值方法 */ textureFr->setWrapMode(QOpenGLTexture::Repeat); QImage bkImage(240, 240, QImage::Format_RGB888); bkImage.fill(Qt::blue); textureBk = new QOpenGLTexture(bkImage); textureBk->setMinificationFilter(QOpenGLTexture::Linear); /* 缩小图片插值方法 */ textureBk->setMagnificationFilter(QOpenGLTexture::Nearest); /* 放大图片插值方法 */ textureBk->setWrapMode(QOpenGLTexture::Repeat); program->link(); program->bind(); } void MzOpenGLWidget::paintGL() { GLfloat vertices[] = { -0.8f, 0.8f, -0.8f, -0.8f, 0.8f, 0.8f, 0.8f, -0.8f, }; GLfloat coors[] = /* 此数组和vertices数组一一对应 */ { 0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, }; QMatrix4x4 matrix; matrix.perspective(53.1300964f, 1.0f, 0.1f, 100.0f); matrix.translate(0, 0, -2); matrix.rotate(angle, 0, 1, 0); program->setUniformValue("trans", matrix); program->enableAttributeArray("trans"); program->setAttributeArray("pos", vertices, 2); program->enableAttributeArray("pos"); program->setAttributeArray("itextCoor", coors, 2); program->enableAttributeArray("itextCoor"); program->setUniformValue("imageFr", 0); program->setUniformValue("imageBk", 1); textureFr->bind(0); textureBk->bind(1); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); } void MzOpenGLWidget::resizeGL(int w, int h) { } float MzOpenGLWidget::rotate() const { return angle; } void MzOpenGLWidget::setRotate(float value) { angle = value; update(); } float MzOpenGLWidget::calcRawRatio() { float a = 50, b = 55; /* f(a) < 1, f(b) > 1 */ while (fabs(a - b) >= 0.00001f) { float c = (a + b) / 2; QMatrix4x4 matrix; matrix.perspective(c, 1.0f, 0.1f, 100.0f); matrix.translate(0, 0, -2); matrix.rotate(0, 0, 1, 0); QRectF destRect = matrix.mapRect(QRectF(0, 0, 100, 100)); qreal rate = 100.0 / destRect.width(); /* 大于1缩小 */ if (rate > 1.0) { b = c; } else { a = c; } } return a; }
标签:贴图,MzOpenGLWidget,QOpenGLTexture,matrix,例程,void,float,Qt3D,program From: https://www.cnblogs.com/mengxiangdu/p/17683322.html