首页 > 其他分享 >Qt3D曲面正反面贴图例程

Qt3D曲面正反面贴图例程

时间:2023-09-06 20:34:50浏览次数:51  
标签:贴图 MzOpenGLWidget QOpenGLTexture matrix 例程 void float Qt3D program

主要利用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

相关文章

  • Web编辑器实现WORD粘贴图片自动上传
    ​ 这种方法是servlet,编写好在web.xml里配置servlet-class和servlet-mapping即可使用后台(服务端)java服务代码:(上传至ROOT/lqxcPics文件夹下)<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%><%@     page contentType="text/html;cha......
  • DW1000的CCA例程
    DW1000的CCA例程介绍​ 对于无线传感器网络应用,大多数的MAC协议都依赖于ClearChannelAssessment(CCA)来避免冲突。这包括对空中信号进行采样,检测信道是否空闲。一般的无线电可以通过检测载波信号来实现,但是对于UWB技术来说是不行的。对于UWB技术来说,一种可行的方案是只寻找前......
  • PIOC-PIOC参考应用例程使用说明
    CH32X035芯片PIOC参考应用例程使用说明引言:CH32X035芯片内,嵌入了一个可编程协议I/O微控制器PIOC,即eMCU,该eMCU基于单时钟周期精简指令集的RISC8B内核,运行于系统主频,具有2K指令的程序ROM和49个SFR寄存器及PWM定时/计数器,支持2个I/O引脚的协议控制。在......
  • Qt绘制3D图形例程
    本文主要内容是关于QOpenGLWidget的使用。此控件用于代替旧的QGLWidget类。关于此类的使用方法可以参考Qt帮助相关内容。glDrawArrays(...)函数参数说明:OpenGL理解GL_TRIANGLE_STRIP、GL_TRIANGLE_FAN等绘制三角形序列的三种方式_匆忙拥挤repeat的博客-CSDN博客变量修饰符说明......
  • vscode 中 Markdown 粘贴图片的位置
    背景自从typora开始收费后,不少人开始寻找其他的Markdown编辑器,我觉得vscode就是一个很不错的选择虽然不能像typora在Markdown预览中编辑,但是左右布局对于一个前端工程师来说已是习以为常PS:自从github被微软收购后,github开始使用网页版的vscode编辑器......
  • 关于CH32V307 RT-Thread例程配置使用FPU注意事项
    关于在CH32V307EVTRT-Thread例程基础上配置修改使用FPU操作流程CH32V307EVT下载链接:https://www.wch.cn/downloads/CH32V307EVT_ZIP.html 1、首先需要注意对MRS进行配置,具体配置方式可参考下贴:https://blog.csdn.net/qq_36353650/article/details/127262634 2、除上述......
  • Blender如何给fbx模型添加材质贴图并导出带有材质贴图的模型
    推荐:使用NSDT场景编辑器快速助你搭建可二次编辑的3D应用场景此教程适合新手用户,专业人士直接可直接绕路。  本教程中介绍了利用Blender建模软件,只需要简单几步就可以为模型添加材质贴,图,并且导出带有材质的模型文件。1、第一步,打开Blender软件,导入模型:(本教程使用一个简单立方......
  • TwinCAT3中通过PLC修改Coe参数的例程
    CoE接口的驱动器,要在PLC程序中修改驱动器参数,可以使用CoeSDO通讯的方式。CoeSDO通讯的功能块包括FB_EcCoeSdoRead,FB_EcCoeSdoWrite,FB_EcCoeSdoReadEx,FB_EcCoeSdoWriteEx等,属于库文件TcEtherCAT.Lib。以FB_EcCoeSdoWriteEx为例。首先导入Tc2_Ether......
  • 基于三维人脸网格模型的二维人脸纹理贴图matlab仿真
    1.算法理论概述      二维人脸纹理贴图是计算机视觉领域中的一个重要研究方向,其目的是将三维人脸模型的纹理信息映射到二维图像上,以便于进行人脸识别、表情分析等应用。本文将详细介绍基于三维人脸网格模型的二维人脸纹理贴图的实现步骤和数学公式。 1.1三维人脸网格模......
  • [8月摸鱼计划] MILKV DUO可以实现的功能及例程
    MILKVDUO是一个基于深度学习的计算机视觉库,它提供了许多功能和例程来处理图像和视觉任务。下面是几个MILKVDUO可以实现的功能以及相应的功能例程:图像分类(ImageClassification):功能:将输入的图像分为不同的类别或标签。例程:使用预训练的卷积神经网络(CNN)对图像进行分类,例如将猫和狗......