Dust3D项目实训四 | 基于modelmeshbinder类的网格纹理绑定功能分析

2021SC@SDUSC

分析概括

功能分析

模型通过面片粘合将二维平面合并在一起生成三维模型。modelmeshbinder类通过层层迭代的思路判断是否产生新网格。从最初的网格点开始判断,如果这些网格点间产生多个新的网格和法线,就删除初始的网格,留下新产生的网格继续迭代,直至形成可以确定出唯一几何体的网格模型,确定后在进行面片的粘合以及UV纹理的绑定。

图片

库函数QOpengl学习

QOpengl是基于QT的Opengl功能集合,其中的QOpenGLTexture类封装了OpenGl纹理对象,可实现Opeb纹GL纹理及其提供的各种功能,其基本函数功能如下:

1、纹理创建

m_texture = new QOpenGLTexture(QImage(":/images/side6.png").mirrored());

2、纹理过滤

m_texture->setMinificationFilter(QOpenGLTexture::Nearest);
m_texture->setMagnificationFilter(QOpenGLTexture::Linear);

3、纹理环绕

m_texture->setWrapMode(QOpenGLTexture::Repeat);

关键代码分析

基于paint函数的纹理绑定

1、网格纹理绑定

if (m_mesh)
   {//如果网格存在
       m_hasTexture = nullptr != m_mesh->textureImage();//判断网格是否存在纹理
       delete m_texture;
       m_texture = nullptr;
       if (m_hasTexture) 
       {//如果网格存在纹理,将此纹理赋予该网格形成平面
           if (m_checkUvEnabled) {//查找UV图并进行纹理绑定
               static QImage *s_checkUv = nullptr;
               if (nullptr == s_checkUv)
                     s_checkUv = new QImage(":/resources/checkuv.png");
            m_texture = new QOpenGLTexture(*s_checkUv);
        } else {
             m_texture = new QOpenGLTexture(*m_mesh->textureImage());
           }
   }

2、法线纹理(贴图/映射)绑定

m_hasNormalMap = nullptr != m_mesh->normalMapImage();//判断是否存在法线贴图
delete m_normalMap;//若存在,删除初始法线贴图
m_normalMap = nullptr;
if (m_hasNormalMap)//为新的法线贴图赋予纹理
    m_normalMap = new QOpenGLTexture(*m_mesh->normalMapImage());
                
m_hasMetalnessMap = m_mesh->hasMetalnessInImage();
m_hasRoughnessMap = m_mesh->hasRoughnessInImage();
m_hasAmbientOcclusionMap = m_mesh->hasAmbientOcclusionInImage();
delete m_metalnessRoughnessAmbientOcclusionMap;
m_metalnessRoughnessAmbientOcclusionMap = nullptr;
if (nullptr != m_mesh->metalnessRoughnessAmbientOcclusionImage() &&(m_hasMetalnessMap || m_hasRoughnessMap || m_hasAmbientOcclusionMap))
m_metalnessRoughnessAmbientOcclusionMap = new QOpenGLTexture(*m_mesh->metalnessRoughnessAmbientOcclusionImage());            

3、环境辐射纹理绑定

if (program->isCoreProfile() &&m_environmentLightEnabled) {//如果存在环境辐射纹理
                    if (nullptr == m_environmentIrradianceMap) {
                        DdsFileReader irradianceFile(":/resources/cedar_bridge_irradiance.dds");
                        m_environmentIrradianceMap = irradianceFile.createOpenGLTexture();
                    }
                    
                    if (nullptr == m_environmentSpecularMap) {
                        DdsFileReader specularFile(":/resources/cedar_bridge_specular.dds");
                        m_environmentSpecularMap = specularFile.createOpenGLTexture();
                    }
                }

基于paint函数的网格纹理映射应用

使用QOpenGLVertexArrayObject进行管线渲染时,通常使用VAO、VBO的方法进行点到点之间的映射,具体流程如下:

初始化渲染
绑定VAO绑定VAO
为此可视对象设置顶点数据状态调用glDraw*()函数
取消绑定解除绑定
QOpenGLVertexArrayObject::Binder vaoBinder(&m_vaoTriangle);//为三角形绑定VAO
                    if (m_vboTriangle.isCreated())
                        m_vboTriangle.destroy();
                    m_vboTriangle.create();
                    m_vboTriangle.bind();
                    m_vboTriangle.allocate(m_mesh->triangleVertices(), m_mesh->triangleVertexCount() * sizeof(ShaderVertex));
                    m_renderTriangleVertexCount = m_mesh->triangleVertexCount();
                    QOpenGLFunctions *f = QOpenGLContext::currentContext()->functions();
                    f->glEnableVertexAttribArray(0);//顶点属性数组
                    f->glEnableVertexAttribArray(1);
                    f->glEnableVertexAttribArray(2);
                    f->glEnableVertexAttribArray(3);
                    f->glEnableVertexAttribArray(4);
                    f->glEnableVertexAttribArray(5);
                    f->glEnableVertexAttribArray(6);
                    f->glEnableVertexAttribArray(7);
                    f->glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(ShaderVertex), 0);//顶点属性点
                    f->glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(ShaderVertex), reinterpret_cast<void *>(3 * sizeof(GLfloat)));
                    f->glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, sizeof(ShaderVertex), reinterpret_cast<void *>(6 * sizeof(GLfloat)));
                    f->glVertexAttribPointer(3, 2, GL_FLOAT, GL_FALSE, sizeof(ShaderVertex), reinterpret_cast<void *>(9 * sizeof(GLfloat)));
                    f->glVertexAttribPointer(4, 1, GL_FLOAT, GL_FALSE, sizeof(ShaderVertex), reinterpret_cast<void *>(11 * sizeof(GLfloat)));
                    f->glVertexAttribPointer(5, 1, GL_FLOAT, GL_FALSE, sizeof(ShaderVertex), reinterpret_cast<void *>(12 * sizeof(GLfloat)));
                    f->glVertexAttribPointer(6, 3, GL_FLOAT, GL_FALSE, sizeof(ShaderVertex), reinterpret_cast<void *>(13 * sizeof(GLfloat)));
                    f->glVertexAttribPointer(7, 1, GL_FLOAT, GL_FALSE, sizeof(ShaderVertex), reinterpret_cast<void *>(16 * sizeof(GLfloat)));
                    m_vboTriangle.release();
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值