Qt 3D教程(三)实现对模型材质參数的控制

蒋彩阳原创文章,首发地址:http://blog.csdn.net/gamesdev/article/details/47131841。欢迎同行前来探讨。

上一篇教程介绍的是显示一个三维模型的基本步骤,接下来我们须要实现的是加入材质,而且希望我们通过button来控制材质的參数。

这种效果看起来非常像一个3D模型材质编辑器的样子。

那我们来尝试一下吧。

首先我们对Settings这个类进行改动,给它增添一些属性,比方说环境光、漫反射、镜面反射以及反射系数。

通过Q_PROPERTY宏以及一系列的setter和getter函数,我们就能够做到这一点。

class Settings: public QObject
{
Q_OBJECT
Q_PROPERTY( bool showModel READ showModel WRITE setShowModel NOTIFY showModelChanged )
Q_PROPERTY( QColor ambient READ ambient WRITE setAmbient NOTIFY ambientChanged )
Q_PROPERTY( QColor diffuse READ diffuse WRITE setDiffuse NOTIFY diffuseChanged )
Q_PROPERTY( QColor specular READ specular WRITE setSpecular NOTIFY specularChanged )
Q_PROPERTY( float shininess READ shininess WRITE setShininess NOTIFY shininessChanged )
public:
explicit Settings( QObject* parent = Q_NULLPTR ); bool showModel( void ) { return m_showModel; }
void setShowModel( bool showModel ); QColor ambient( void ) { return m_ambient; }
void setAmbient( const QColor& ambient ); QColor diffuse( void ) { return m_diffuse; }
void setDiffuse( const QColor& diffuse ); QColor specular( void ) { return m_specular; }
void setSpecular( const QColor& specular ); float shininess( void ) { return m_shininess; }
void setShininess( float shininess );
signals:
void showModelChanged( void );
void ambientChanged( void );
void diffuseChanged( void );
void specularChanged( void );
void shininessChanged( void );
protected:
bool m_showModel;
QColor m_ambient, m_diffuse, m_specular;
float m_shininess;
};

以下是Settings一些函数的实现:

Settings::Settings( QObject* parent ): QObject( parent )
{
m_showModel = true;
m_ambient = QColor( 153, 51, 26 );
m_diffuse = QColor( 51, 153, 26 );
m_specular = QColor( 153, 230, 26 );
m_shininess = 0.6;
} void Settings::setShowModel( bool showModel )
{
if ( m_showModel == showModel ) return;
m_showModel = showModel;
emit showModelChanged( );
} void Settings::setAmbient( const QColor& ambient )
{
if ( m_ambient == ambient ) return;
m_ambient = ambient;
emit ambientChanged( );
} void Settings::setDiffuse( const QColor& diffuse )
{
if ( m_diffuse == diffuse ) return;
m_diffuse = diffuse;
emit diffuseChanged( );
} void Settings::setSpecular( const QColor& specular )
{
if ( m_specular == specular ) return;
m_specular = specular;
emit specularChanged( );
} void Settings::setShininess( float shininess )
{
if ( m_shininess == shininess ) return;
m_shininess = shininess;
emit shininessChanged( );
}

随后我们声明槽函数,点击环境光、漫反射和镜面反射的时候。它都会设置button的背景色,然后设置m_settings的相关成员。

void MainWindow::decorateButton( QPushButton* button, const QColor& color )
{
QString styleSheetTemplate( "background: rgb( %1, %2, %3 )" );
QString styleSheet = styleSheetTemplate.
arg( color.red( ) ).arg( color.green( ) ).
arg( color.blue( ) );
button->setStyleSheet( styleSheet );
} void MainWindow::on_ambientButton_clicked()
{
QPushButton* button = qobject_cast<QPushButton*>( sender( ) );
QColor color, prevColor;
prevColor = m_settings.ambient( );
color = QColorDialog::getColor( prevColor, this, "请选择一个颜色" );
decorateButton( button, color );
m_settings.setAmbient( color );
} void MainWindow::on_diffuseButton_clicked()
{
QPushButton* button = qobject_cast<QPushButton*>( sender( ) );
QColor color, prevColor;
prevColor = m_settings.diffuse( );
color = QColorDialog::getColor( prevColor, this, "请选择一个颜色" );
decorateButton( button, color );
m_settings.setDiffuse( color );
} void MainWindow::on_specularButton_clicked()
{
QPushButton* button = qobject_cast<QPushButton*>( sender( ) );
QColor color, prevColor;
prevColor = m_settings.specular( );
color = QColorDialog::getColor( prevColor, this, "请选择一个颜色" );
decorateButton( button, color );
m_settings.setSpecular( color );
} void MainWindow::on_shininessEdit_returnPressed( void )
{
m_settings.setShininess( ui->shininessEdit->text( ).toFloat( ) );
}

最后我们在QML中加入PhongMaterial这个类,这个类在C++中是Qt3D::Render::QPhongMaterial,它提供了基于Phong光照模型的这种材质,提供了一种很真实的显示效果。我们使用_settings这个上下文属性将上述的材质属性绑定到PhongMaterial中。加入了PhongMaterial的QML代码例如以下:


import Qt3D 2.0
import Qt3D.Renderer 2.0 Entity
{
id: root Camera
{
id: camera
position: Qt.vector3d( 0.0, 20.0, 100.0 )
projectionType: CameraLens.PerspectiveProjection
fieldOfView: 45
aspectRatio: 16.0 / 9.0
nearPlane : 0.1
farPlane : 1000.0
upVector: Qt.vector3d( 0.0, 1.0, 0.0 )
viewCenter: Qt.vector3d( 0.0, 20.0, 0.0 )
} components: FrameGraph
{
ForwardRenderer
{
clearColor: Qt.rgba( 0.2, 0, 0, 1 )
camera: camera
}
} Entity
{
Mesh
{
id: chestMesh
source: "qrc:/assets/Chest.obj"
enabled: _settings.showModel
} // 新加入的内容
PhongMaterial
{
id: phongMaterial
ambient: _settings.ambient
diffuse: _settings.diffuse
specular: _settings.specular
shininess: _settings.shininess
} components: [ chestMesh, phongMaterial ]
} Configuration
{
controlledCamera: camera
}
}

程序执行截图例如以下:

本次教程的代码均在我的github中,感兴趣的同行们能够通过git clone或者是直接下载我的git项目来获取到本套教程的全部源码。

Qt 3D教程(三)实现对模型材质參数的控制的更多相关文章

  1. Hadoop作业性能指标及參数调优实例 (三)Hadoop作业性能參数调优方法

    作者: Shu, Alison Hadoop作业性能调优的两种场景: 一.用户观察到作业性能差,主动寻求帮助. (一)eBayEagle作业性能分析器 1. Hadoop作业性能异常指标 2. Had ...

  2. Qt 3D教程(二)初步显示3D的内容

    Qt3D教程(二)初步显示3D的内容 前一篇很easy,全然就没有牵涉到3D的内容,它仅仅是我们搭建3D应用的基本框架而已,而这一篇.我们将要利用它来初步地显示3D的内容了! 本次目的是将程序中间的内 ...

  3. Chromium与CEF的多进程模型及相关參数

    CEF基于Chromium,也是多进程模型.关于进程模型.參考这里:https://www.chromium.org/developers/design-documents/process-model ...

  4. [译]Vulkan教程(31)加载模型

    [译]Vulkan教程(31)加载模型 Loading models 加载模型 Introduction 入门 Your program is now ready to render textured ...

  5. Chem 3D中怎么创建立体模型

    ChemDraw作为一款很受大家欢迎的化学绘图软件,其在绘制平面化学方面的功能已经非常的强大了,其实它也可以绘制3D图形.Chem 3D就是绘制3D图形的重要组件.而且为了满足不同的用户绘图的需求,可 ...

  6. 使用Qt 3D Studio 2.4显着提升性能(渲染速度提高了565%)

    发布于2019年6月18日星期二11评论Qt 3D Studio 2.4显着改善性能 发表于Biz Circuit&Dev Loop,设计,图形,性能,Qt 3D Studio 除了有效使用系 ...

  7. 『MXNet』第三弹_Gluon模型参数

    MXNet中含有init包,它包含了多种模型初始化方法. from mxnet import init, nd from mxnet.gluon import nn net = nn.Sequenti ...

  8. 移植QT5.6到嵌入式开发板(史上最详细的QT移植教程)

    目前网上的大多数 QT 移植教程还都停留在 qt4.8 版本,或者还有更老的 Qtopia ,但是目前 Qt 已经发展到最新的 5.7 版本了,我个人也已经使用了很长一段时间的 qt5.6 for w ...

  9. Smart3D系列教程8之 《模型合并——相邻地区多次建模结果合并》

    迄今为止,Wish3D已经出品推出了7篇系列教程,从倾斜摄影的原理方法.采集照片的技巧.Smart3D各模块的功能应用.小物件的照片重建.大区域的地形重建到DSM及正射影像的处理生产,立足于建模软件的 ...

随机推荐

  1. socket编程之二:两种链接类型tcp和udp

    前面一篇文章说到了一些计算机网络的基础知识.引入了socket.从这节開始,就进入正题了. 一 概述 TCP:Transimission Control Protocol传输控制协议. UPD:Use ...

  2. Android自己定义View之组合控件 ---- LED数字时钟

    先上图 LEDView效果如图所看到的. 之前看到一篇博客使用两个TextView实现了该效果.于是我想用自己定义控件的方式实现一个LEDView.使用时就可以直接使用该控件. 採用组合控件的方式,将 ...

  3. Ruby学习(三)——类与对象(1)

    今天看了<Ruby元编程>,感觉内容新颖翔实,是Ruby中难得的一见的好书,在此推荐给大家.其实今天看的主要是第一章的第一部分,先把内容梳理一下,也许这一部分会分成几天的内容来给大家介绍吧 ...

  4. CZLayer的阴影

    CALayer有一个shadow属性 意思是阴影 shadowcolor  //颜色 shadowoffset  //偏移 shadowOpacity  //透明度 layer有一个方法    mas ...

  5. Linux命令学习-curl

    作用 curl是利用URL语法的一款强大的网络工具,你可以使用它完成上传下载文件等操作. curl http://www.cnblogs.com 上诉的命令即可将页面内容打印到屏幕上. 常用参数 -o ...

  6. Hessian实例

    简述Hessian Hessian是一个由Caucho Technology开发的轻量级RPC框架,由于它使用二进制RPC协议,所以它更快.更简单,很适合于发送二进制数据(访问官网): 在进行基于He ...

  7. ROS-SLAM仿真-cartographer

    前言:cartographer是谷歌2016年发布的一个开源slam算法,采用基于图网络的优化方法,主要基于激光雷达来实现. 使用源码编译方式. 一.新建工作空间 1.1 使用roboware新建名为 ...

  8. DataBaseFactory基础了解

     <add name="Connection str" connectionString="data source=.;pwd=12;uid=sa;database ...

  9. call使用场景

    在javascript OOP中,定义: function cat(){    }    cat.prototype={    food:"fish",    say: funct ...

  10. Photoshop把图片调成固定的像素。

    1.用PhotoShop打开需要修改的图片. 2.点击“窗口”菜单的“图层”子菜单,打开图层控制面板(快捷键F7).3.用鼠标左键双击“图层”面板的“背景”图层.在弹出窗口中点击“确定”按钮,解锁背景 ...