glTF格式初步了解



  • glTF格式初步了解

    最近看到Qt 3D的进展,偶然了解到了一种新的格式:glTF格式。这种格式据说比现有的3D格式更加符合OpenGL应用的需要,这引起了我的好奇,于是我在Qt 3D的外部链接中找到了有关glTF的相关链接。

    glTF的官网介绍在这里。它介绍了glTF的一些特性、发起者以及应用情景。官网中,介绍了glTF是一种可以减少3D格式中与渲染无关的冗余数据并且在更加适合OpenGL簇加载的一种3D文件格式。glTF的提出是源自于3D工业和媒体发展的过程中,对3D格式统一化的急迫需求。官网的一张图片可以简单地说明这一点:
    0_1452475728449_image.png
    也就是说,glTF立志成为音频界的mp3、视频界的H.264,图片界的jpeg。
    在官网的截图上我们看到,在没有glTF的时候,大家都要花很长的的时间来处理模型的载入。很多的游戏引擎或者工控渲染引擎,都使用的是插件的方式来载入各种格式的模型。可是,各种格式的模型都包含了很多无关的信息。比如说.blend格式包含了场景、灯光、摄像机信息,也包含了blender的元信息,这样在载入的时候会浪费很多的载入时间。这需要一次模型的再加工工序(这道工序是否需要,有待观察)
    0_1452475756946_image.png
    当有glTF之后,可以将模型再加工成为glTF,这样渲染的程序只需要支持glTF格式就可以很顺利地处理各种情况了。
    0_1452475824291_image.png
    给大家简单介绍了一下glTF这个格式,下面我说一下我对glTF这个新的3D格式的看法。

    1、为什么要有glTF这个格式的提出呢?
    首先,一切新的事物的发明都是为了为了解决以前不方便的情况。就glTF格式而言,虽然以前有很多3D格式,但是各种3D模型渲染程序都要处理很多种的格式。对于那些对载入格式不是那么重要的软件(不是那些类似“格式工厂”那样的软件),可以显著减少代码量,所以也有人说,最大的受益者是那些对程序大小敏感的3D Web渲染引擎,只需要很少的代码就可以顺利地载入各种模型了。此外,glTF是对近二十年来各种3D格式的总结,使用最优的数据结构,来保证最大的兼容性以及可伸缩性。这就好比是本世纪初xml的提出。glTF使用json格式进行描述,也可以编译成二进制的内容:bglTF。glTF可以包括场景、摄像机、动画等,也可以包括网格、材质、纹理,甚至包括了渲染技术(technique)、着色器以及着色器程序。同时由于json格式的特点,它支持预留一般以及特定供应商的扩展。

    2、为什么要提出一个新的格式而不是发展现有的格式比如说collada?
    我认为这个是对3D通用格式的解释权的一种争夺战。大家已经知道OpenGL已经成为事实上的工业渲染标准,作为现有OpenGL的维护组织,khronos也迫切希望在3D格式上进行一次统一,让glTF成为类似jpeg、mp3等常见的格式,khronos也有威望,可以让行业的大厂们协同一起来参与新标准的制定。对于collada这样基于xml格式的竞争对手,glTF的提出给大家提供了一个新的思路以及解决方案。就好像json当初没有提出的时候,大家都会倾向使用xml来描述通用的可交换的数据格式,可是随着json的发展,xml不再是一枝独秀,逐渐形成了两强的局面,大家也有了更多的选择。上图我们可以看到,我们可以利用现有的格式转换工具很轻松地将collada格式转换为glTF格式,而glTF对于OpenGL的兼容性,我想会因khronos而变得更好。


Log in to reply
 

走马观花

最近的回复

  • C

    Qt for MCU需要商业授权的

    read more
  • Qt for MCUs

    搭建Qt for MCUs PC端开发环境。qt for mcus提供了一个完整的图形框架和工具包,包含了在MCUs上设计、开发和部署gui所需的一切。它允许您在裸机或实时操作系统上运行应用程序。

    先决条件

    开发主机环境支持仅限于Windows 10

    MSVC compiler v19.16 (Visual Studio 2017 15.9.9 or newer) x64

    CMake v3.13 or newer (you can install it using the Qt Online installer) x64

    使用Qt联机安装程序安装Qt for MCUs,该安装程序可通过Qt帐户下载

    安装Qt 5.14和Qt Creator 4.11 or higher

    安装链接

    › Qt: https://account.qt.io/downloads
    › CMake: https://cmake.org/download/
    › Python 2.7 32-bit: https://www.python.org/downloads/release/python-2716/
    › Arm GCC: https://developer.arm.com/tools-and-software/open-source-software/developer-tools/gnutoolchain/gnu-rm/downloads
    › J-Link Software Pack: https://www.segger.com/downloads/jlink/JLink_Windows.exe
    › J-Link OpenSDA Firmware: https://www.segger.com/downloads/jlink/OpenSDA_MIMXRT1050-EVKHyperflash
    › STM32CubeProgrammer: https://www.st.com/en/development-tools/stm32cubeprog.html
    › STM32 ST-LINK Utility: https://www.st.com/en/development-tools/stsw-link004.html​​​​​​​

    Qt Creator设置 启用Qt Creator插件 选择“帮助>关于插件”,然后从列表中选择“MCU支持(实验性)”插件,重新启动Qt Creator以应用更改
    替代文字 为MCU创建Qt工具包

    选择工具>选项>设备>MCU

    选择Qt for MCUs-Desktop 32bpp作为目标

    如果尚未设置,请提供Qt for MCUs安装目录的路径。

    单击Apply应用。

    替代文字

    替代文字
    替代文字

    注意:

    编译器要选X64,Qt版本要选64bit,CMake Tool选x64

    打开恒温器项目demo

    选择文件>打开文件或项目。。。

    打开CMakefiles.txt文件来自thermo文件夹的文件。

    选择Qt作为MCU-桌面32bpp套件。

    单击“配置项目”以完成。

    替代文字

    问题

    开发主机环境支持仅限于Windows 10

    C++编译失败,文本大字体.pixelSize.

    文本类型无法正确呈现需要复杂文本布局的unicode序列。对复杂文本使用StaticText

    read more
  • H

    hi 有问题请教你,方便加个联系方式吗

    read more
  • boost.asio是一个很棒的网络库,这回儿我也开始系统地学习起来了。想想当年接触boost,也有八年多了。这次开始接触boost,觉得既熟悉又陌生。熟悉的是小写字母+下划线的命名方式、晦涩的模板、很慢的编译速度以及较大的程序体积,陌生的是asio的各种概念:io服务、接收器、套接字等等:我之前对网络编程不是非常了解。

    于是根据我的理解,参考《Boost.Asio C++网络编程》实现了这样一个简单的客户端和服务端通信的例子,例子非常简单,还不完善,但是幸运的是,可以在本机上互通了。
    下面是客户端的代码:

    #include <iostream> #include <boost/asio.hpp> #include <boost/proto/detail/ignore_unused.hpp> using namespace std; using namespace boost::asio; using namespace boost::system; using namespace boost::proto::detail;// 提供ignore_unused方法 void writeHandler( const boost::system::error_code& ec, size_t bytesTransferred ) { if ( ec ) { cout << "Write data error, code: " << ec.value( ) << "transferred: " << bytesTransferred << endl; } else { cout << "OK! " << bytesTransferred << "bytes written. " << endl; } } int main(int argc, char *argv[]) { ignore_unused( argc ); ignore_unused( argv ); io_service service; ip::tcp::socket sock( service ); ip::tcp::endpoint ep( ip::address::from_string( "127.0.0.1" ), 6545 ); boost::system::error_code ec; sock.connect( ep, ec ); if ( ec ) { cout << "Connect error, code: " << ec.value( ) << ", We will exit." << endl; return ec.value( ); } else { char buf[1024] = "Hello world!"; sock.async_write_some( buffer( buf ), writeHandler ); sock.close( ); } return service.run( ); }

    下面是服务端的代码:

    #include <iostream> #include <boost/asio.hpp> #include <boost/proto/detail/ignore_unused.hpp> using namespace std; using namespace boost::asio; using namespace boost::system; using namespace boost::proto::detail;// 提供ignore_unused方法 void acceptHandle( const boost::system::error_code& code ) { cout << "Accepted." << endl; } int main(int argc, char *argv[]) { ignore_unused( argc ); ignore_unused( argv ); io_service service; ip::tcp::endpoint ep( ip::address::from_string( "127.0.0.1" ), 6545 ); boost::system::error_code ec; ip::tcp::socket sock( service ); ip::tcp::acceptor acceptor( service, ep ); acceptor.async_accept( sock, acceptHandle ); if ( ec ) { cout << "There is an error in server. code: " << ec.value( ) << endl; } return service.run( );// 阻塞运行 }

    运行结果是这样的:
    78448d7b-b3ae-42fc-9e2e-4dd2fbdac2c2-image.png

    我对boost.asio中几个概念的理解:

    io_service,这就是一个类似事件循环的东西,它为io设备提供服务,故名。不管是套接字、文件还是串口设备,都要使用它的服务。它的run()函数相当于启动了一个事件循环。一旦有消息了,即进行响应。这也是实现异步编程的重要基础。 socket,这个类则是套接字,可以处理TCP或者是UDP请求。有同步以及异步的处理方式,也有带异常以及不带异常的处理方式。 acceptor,接收器,仅仅是服务端使用。相当于其余框架中的listener,作接收用的。

    比较浅显,如果有不当之处,敬请指正。

    read more

关注我们

微博
QQ群