ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

DRACO库在win10+MSVC2019下的预编译资源与CMake接入详解

DRACO库在win10+MSVC2019下的预编译资源与CMake接入详解 简介DRACO编译完成的库win10MSVC2019-64是一份面向Windows开发者的预编译库省去了从源码编译DRACO的繁琐步骤。DRACO是谷歌开源的三维几何网格压缩技术在三维资源传输、实时渲染、点云处理和Web3D等场景中可显著减小模型体积并尽量保持视觉细节因而得到广泛关注。这份库已按MSVC2019工具链编译完成整体以7z格式打包共418个文件、约7.41MB其中402个h头文件提供完整的API声明8个cmake文件支持直接导入CMake工程4个exe为自带的命令行编码与解码工具可用于快速压缩与解压网格文件另有2个pc和2个lib负责链接与包配置覆盖了项目集成所需的基本文件组成。目前已有159人学习下载适合需要在Visual Studio 2019环境中集成DRACO的C工程师。借助这份编译好的库读者可以跳过环境配置和编译错误排查将更多时间用于网格压缩效果验证快速在自己的项目中启用DRACO能力。1. 为什么建议直接用编译好的 DRACO一份免折腾的 win10MSVC2019-64 资源做三维模型处理和点云压缩应用的同行对 DRACO 应该不陌生——Google 开源的三维几何压缩库专治网格数据体积过大。但真要把它集成进自己的工程很多人会卡在“先编译”这一步CMake 参数、编译器版本、静态还是动态库稍不注意就是一下午的血泪折腾。这篇笔记拆的是一份在 win10 MSVC2019-64 环境下编译完成的 DRACO 库资源里面既有 draco_encoder.exe 和 draco_decoder.exe 两个命令行工具也有配套的 CMake config 与 targets 文件拿回来可以直接接入 CMake 工程。我会把这套资源的文件角色、接入方式、命令行参数和踩过的坑全部过一遍适合正在用 MSVC 工具链开发三维工具的读者。2. 这份资源里到底有什么CMake 配置文件与可执行文件的角色拆解拿到一个压缩包第一反应是看文件列表。这份资源看起来文件不少实际分成三类CMake 包配置文件、Release/Debug 链接描述文件、命令行压缩工具。每个文件各管一段搞清楚它们的分工才能把库正确嵌进自己的工程。2.1 文件清单与各自职责文件类型作用draco-config.cmakeCMake 包配置find_package(draco CONFIG)的入口文件draco-config-version.cmakeCMake 包配置版本比较与兼容性检查draco-targets.cmake导入目标定义 draco 相关的 imported targetdraco-targets-release.cmake链接描述Release 配置使用的链接参数draco-targets-debug.cmake链接描述Debug 配置使用的链接参数draco_encoder.exe命令行工具网格/点云文件压缩为 .drcdraco_decoder.exe命令行工具.drc 解码还原为网格文件draco-config.cmake是整个资源被 CMake 识别的关键。CMake 在 CONFIG 模式下找到这个文件才会认为系统中存在一个叫 draco 的包。draco-config-version.cmake是配套的版本校验文件当工程里写了find_package(draco 1.5 CONFIG REQUIRED)这类版本约束时CMake 会先读取它判断版本是否满足。draco-targets.cmake里保存的是构建完成后导出的 imported target也就是把库文件、头文件路径、依赖项绑定成一个 CMake 目标对象工程里只需要target_link_libraries引用它。release 和 debug 分开两份描述文件是 CMake 安装导出的默认做法核心目的是防止链接器把 Debug 配置的工程链到 Release 库上。之前遇到过一位朋友图省事手工改了 targets 文件把两份合并随后链接阶段冒出一堆LNK2038原因就是配置被搞乱了。两个 exe 属于开箱即用的命令行工具不依赖 DRACO 的动态库。它们的价值在于不需要先写代码就能把一批模型压缩成 .drc适合做资产处理和效果验证。2.2 这套文件是怎么产生的决定了怎么用DRACO 官方源码采用 CMake 构建常规流程是cmake配置生成解决方案编译完成后执行cmake --install把产物安装到指定前缀目录安装目录里就会出现draco-config.cmake、draco-targets.cmake这一系列文件。这份资源里的文件形态本质就是 install 阶段的结果被整体打包出来了。这意味着两件事。第一这是一套独立的、自包含的包不依赖 Visual Studio 的安装目录放到任何路径下都能被引用。第二接入工程时不能用添加源码目录的方式去add_subdirectory那是给源码准备的这里应该走包引用的方式把资源根目录告诉 CMake让它通过find_package(draco CONFIG)完成搜索。实际使用中draco-config.cmake内部会去加载draco-targets.cmake后者再根据当前构建配置选择加载 release 还是 debug 描述文件。这个加载链是环环相扣的缺一个文件都会导致find_package直接失败。所以拿到资源后不要自作主张删改文件保持原有结构放进third_party目录即可。2.3 为什么 win10 MSVC2019-64 是个强约束DRACO 核心是 C 静态库里面涉及大量模板与 SIMD 指令编译产物和工具链强绑定。MSVC2019 生成的库文件依赖对应的 C 运行库和标准库实现如果你的工程恰好也是 win10 MSVC2019 64 位那链接阶段基本无障碍。如果工程换成了 MinGW 或 ClangCL静态库的 ABI 和符号格式对不上链接器会报一堆 undefined reference换到 VS2022 虽然大体兼容但 DRACO 里部分 intrinsics 代码的生成策略可能随编译器版本变化最稳妥的做法还是保持工具链一致。我在另一台机器上用 VS2022 做过一次测试编译能过但一个含有大量顶点色模型的解码结果出现少量颜色值偏移排查到最后是编译器版本引发的浮点运算差异。所以拿到资源的第一步不是写代码而是确认本机工具链和目标机一致否则后面会遇到大量链接错误。3. 三分钟接入项目CMake 引用与首轮可运行验证接入一个第三方库最常见的方式是find_package但 DRACO 有它的脾气要先确认工具链版本一致再引用正确的 target 名称最后写最小代码验证。下面这套流程是我每次换新机器都会强制走一遍的。3.1 第一步确认本机工具链版本与资源一致在 x64 Native Tools Command Prompt for VS2019 里执行下面的命令确认 cl 和 CMake 都可用。cl 21 | findstr /i Version cmake --version第一行是查看 MSVC 编译器的版本号输出里应包含 19.2x 开头的数字对应 VS2019 的 v142 工具集第二行查看 CMake 版本DRACO 的配置文件要求不苛刻3.16 以上基本没问题。如果 cl 提示“不是内部或外部命令”说明没有安装 C 生成工具或者没进对命令行环境。这里有个容易翻车的点开始菜单里有两个命令行入口一个是 x64 Native Tools一个是 x86 Native Tools。如果开的是 x86 版本后面 CMake 生成出来的工程是 32 位的链接 64 位库必然失败。我一般会先在命令行里敲echo %VSCMD_ARG_TGT_ARCH%输出 x64 再继续。3.2 第二步用 find_package 把库接进 CMake 工程在工程目录下建一个 CMakeLists.txt内容如下。cmake_minimum_required(VERSION 3.16) project(use_draco LANGUAGES CXX) set(CMAKE_CXX_STANDARD 11) set(CMAKE_CXX_STANDARD_REQUIRED ON) # 资源解压后放在 third_party/draco 目录下 set(DRACO_PREFIX ${CMAKE_CURRENT_SOURCE_DIR}/third_party/draco) set(CMAKE_PREFIX_PATH ${DRACO_PREFIX}) # 以 CONFIG 模式查找 draco-config.cmake find_package(draco CONFIG REQUIRED) add_executable(draco_app main.cpp) target_link_libraries(draco_app PRIVATE draco::draco)set(CMAKE_PREFIX_PATH ...)是关键CMake 会在这个路径下搜索draco-config.cmake不设置它find_package 会去系统默认目录碰运气大概率找不到。CONFIG参数强制走配置文件模式而不是模块模式因为 DRACO 不提供FindDraco.cmake。draco::draco是导出目标的名称准确写法以draco-targets.cmake里add_library后面的名字为准常见的是draco_static或draco::draco写错了 configure 阶段会直接报错。提示如果你发现 configure 时报 target 找不到用文本编辑器打开 draco-targets.cmake搜索add_library看到的第一个参数就是正确名称。3.3 第三步写一个最小调用程序验证库可用在工程目录下新建 main.cpp用 Draco 的 Encoder API 读取一个 OBJ 文件并压缩输出。#include draco/compression/encode.h #include cstdio #include fstream #include iostream #include string int main(int argc, char** argv) { if (argc 3) { std::cerr 用法: draco_app 输入网格 输出.drc\n; return 1; } // 创建编码器实例 draco::Encoder encoder; // SetSpeedOptions 两个参数编码速度和解码速度0~10数字越大速度越慢、压缩率越高 encoder.SetSpeedOptions(5, 5); // EncodeFileToBuffer 直接读取文件自动识别 OBJ/PLY 等网格格式 auto result encoder.EncodeFileToBuffer(argv[1]); if (!result.ok()) { std::cerr 编码失败: result.status().error_msg_string() \n; return 1; } std::ofstream out(argv[2], std::ios::binary); out.write(result.value().data(), result.value().size()); std::cout 编码完成输出 result.value().size() 字节\n; return 0; }EncodeFileToBuffer是 DRACO 较新版本提供的接口内部会完成网格解析和压缩省去手动加载 Mesh 的步骤。SetSpeedOptions第一个参数控制编码器搜索压缩策略的强度取 5 是兼顾速度与体积第二个参数控制解码速度一般保持 5 就够。这段代码如果能编译通过并成功输出 .drc 文件说明库本身没有问题问题基本都出在后面的工程配置上。如果编译时提示找不到draco/compression/encode.h说明资源的 include 目录没被正确引入。有些打包版资源只带库和 cmake 文件不带头文件需要从 DRACO 官方源码对应版本的src目录里把draco文件夹拷出来放到 include 路径下。我在 5.1 里会详细说。3.4 第四步用 VS2019 生成器构建并验证在工程根目录执行下面的命令。cmake -S . -B build -G Visual Studio 16 2019 -A x64 cmake --build build --config Release第一条命令指定 Visual Studio 16 2019 生成器-A x64强制生成 64 位工程与库的位数保持一致第二条命令编译 Release 配置。这里不要偷懒省略-A x64CMake 默认会生成 Win32 平台链接时会出现0x0000005这种莫名其妙的崩溃或 LNK 错误。构建成功后找到build/Release/draco_app.exe拿一个 OBJ 模型运行能看到程序输出编码后的字节数说明整个链路已经通了。4. 把命令行跑起来draco_encoder 与 draco_decoder 的参数与典型用法CLI 工具的价值在批量处理和快速验证不需要写任何代码。draco_encoder 负责把网格压成 .drcdraco_decoder 负责解回来。这一章把常用参数和实际场景里的搭配方案讲清楚。4.1 基本用法与输入格式在命令行里执行最简单的编码与解码命令。draco_encoder.exe -i input.obj -o output.drc draco_decoder.exe -i output.drc -o restored.obj-i指定输入文件-o指定输出文件。编码器的输入常见格式有 OBJ、PLY、OFF这三种是 DRACO 官方最稳定的支持格式解码器输入只能是 .drc 或 .glb 中内嵌的 Draco 压缩数据输出格式由-o的文件后缀决定。需要明确一点.drc 是 Draco 私有容器不是通用三维格式只有 Draco 自己的编解码器能读。它的定位是中间传输格式适合 Web 端加载、游戏资源打包、云存储不适合作为最终交付格式。项目里如果有美术同事要打开 .drc还得先转回 OBJ 或 PLY。4.2 关键参数表参数含义默认值说明-cl压缩级别70~10数字越大压缩率越高耗时越长-qp顶点位置量化位数11控制几何精度数值越大越精细-qt纹理坐标量化位数10影响 UV 精度贴图模型的关键-qn法线量化位数8影响光照显示效果-qo顶点颜色量化位数8顶点色模型的颜色精度-qg通用属性量化位数8其他自定义属性的统一设置量化位数的含义是把浮点坐标映射到整数网格时使用的二进制位宽。每减少 1 位精度减半文件体积随之下降。-cl则控制编码器对压缩策略的搜索强度级别越高尝试的组合越多耗时成倍增长。这里有个 DRACO 的玄学现象-cl 10不总是比-cl 5体积小因为高级别会引入更激进的拓扑修改遇到高度不规则网格时反而可能生成更大的编码结果。所以别迷信最高级别实际项目里我会从 7 开始试看体积和耗时变化再定。4.3 批量压缩一个目录下的模型处理三维资产时通常是一批模型一起压手写命令不现实。Windows cmd 和 Linux bash 分别给一个循环示例。# bash 环境下批量压缩 models 目录下所有 obj for f in ./models/*.obj; do base${f%.obj} ./draco_encoder.exe -i $f -o $base.drc -cl 7 -qp 11 -qn 8 done:: cmd 环境下批量压缩 models 目录下所有 obj for %%f in (models\*.obj) do draco_encoder.exe -i %%f -o %%~nf.drc -cl 7 -qp 11 -qn 8bash 版本里${f%.obj}是去掉 .obj 后缀拼出输出文件名cmd 版本里%%~nf的作用相同。两段脚本用的参数都是-cl 7 -qp 11 -qn 8这是静态展示模型的均衡组合几何精度保持常见水平法线量化控制在视觉无感范围内。如果模型只有几何没有贴图-qt可以不加由编码器用默认值处理。4.4 典型场景Web 端展示的增量优化很多开发者把 DRACO 用于 Web 三维展示核心诉求是减少模型下载体积。我的习惯是分场景给参数静态展示模型用-cl 7 -qp 12兼顾体积和视觉质量游戏小道具这类重复资源用-cl 10 -qp 10尽可能压小体积高精度工业零件反而是-cl 5 -qp 14宁可文件大一点也要保住尺寸精度。不管选哪组参数都建议把原始模型归档不要把原始 OBJ 删掉。因为 DRACO 量化是有损的解出来的模型不等同于原始模型后续要重新压缩更高精度的版本只能回到原始数据。5. 避坑记录链接与运行阶段最常见的 5 个翻车现场这些坑来自不同工程和不同机器的反复踩踏每一条都对应真实的报错信息。按“现象 → 原因 → 解决”的顺序记录方便你自己对号入座。5.1 坑一编译时找不到 draco/compression/encode.h现象工程里 include 了draco/compression/encode.h编译报 fatal error C1083提示无法打开包含文件。原因这份资源只带了编译产物和 CMake 配置文件没有把源码中的draco头文件目录一起打包。CMake 的 targets 文件虽然声明了 include 路径但目标路径指向的是开发机上的源码目录换到新机器自然失效。解决从 DRACO 官方源码对应版本的src目录下把整个draco文件夹复制到本地用target_include_directories(draco_app PRIVATE 头文件根目录)指定。注意头文件根目录的层级要保证#include draco/compression/encode.h能找到文件也就是src目录才是根。5.2 坑二链接阶段 RuntimeLibrary mismatch现象编译正常链接时报LNK2038 mismatch detected for RuntimeLibrary后面跟着一堆 MD、MDd、MT、MTd 字样。原因工程和库的运行时库模式不一致。MSVC 下静态库的运行时库必须是笔译的比如库用/MD编译工程就不能用/MTDebug 配置下库用/MDd工程用了/MD同样会翻车。DRACO 的 targets 文件里没有强制改写这些选项默认引用工程自己的设置。解决到工程 CMakeLists.txt 里显式统一 RuntimeLibrary。我一般会在根 CMakeLists 里加一行set(CMAKE_MSVC_RUNTIME_LIBRARY MultiThreadedDLL)这样无论 debug 还是 release 都统一走 MD 系列避免手工改 VS 工程属性遗漏。5.3 坑三新机器运行缺 VCRUNTIME140.dll现象es 文件编译成功换一台干净机器双击 exe弹窗提示缺少 VCRUNTIME140.dll 或 VCRUNTIME140_1.dll。原因MSVC 编译的库和程序默认动态链接到 VC 运行库目标机器没有安装对应版本的 Visual C Redistributable。这份资源里的 exe 也是动态链接的所以在没有运行库的机器上一样会报错。解决在目标机器安装 VC 2015-2022 Redistributable x64。如果希望彻底免安装需要从源码重新编译一份带静态运行库的 DRACO并在工程里同样设置/MT工作量会大不少一般只有发布给终端用户时才值得做。5.4 坑四用 MinGW 去链接 MSVC 的库现象工程用 MinGW 或 Clang 工具链链接时报几百个 undefined reference报错符号看起来很像 DRACO 的类名但后面跟的修饰符不同。原因MSVC 的 lib 文件和 MinGW 的 a 文件虽然都是静态库但 COFF 符号格式和 itanium ABI 命名规则不一样。MSVC 导出的库文件只能被 MSVC 兼容的链接器消费GCC 系工具链无法正确解析。解决确认自己的工程工具链是 MSVC。如果确实要用 MinGW只能从源码自行构建 MinGW 版本不能拿这份资源硬链。另外注意不要混用不同编译器编译的目标文件CMake 在切换工具链后必须清空 build 目录重新 configure。5.5 坑五手工拷贝一半文件导致 find_package 失败现象find_package(draco CONFIG REQUIRED)报错提示找不到 dracoConfig.cmake 或 draco-config.cmake但明明文件就在目录里。原因拷贝文件时只复制了 config 文件漏掉了 targets 文件或者把 draco-targets.cmake 删掉了。CMake 在 CONFIG 模式下搜索到一个残缺的包时会直接判定为 not found而不是尝试继续猜。解决整个资源目录保持完整复制不要按需挑文件。如果确实丢失了 targets 文件最快的方法是回到官方源码 build 目录执行cmake --install . --prefix 要存放的目录重新生成一套完整的安装产物再替换进资源目录。6. 一个值得养成的习惯先解码后编码用回归测量验证调参效果花在调参上的时间如果不用数据佐证大概率只是在自我感动。DRACO 的量化参数一改体积确实变小了但几何精度损失了多少解码耗时涨了多少必须用数据回答。我养成的习惯是每次调整参数都强制跑一遍“编码 → 解码 → 对比原始模型”的流程。6.1 用脚本批量跑参数组合写一个 Python 脚本自动执行 enc / dec 并记录耗时和体积。import os import subprocess import time MODELS [mannequin.obj, bunny.ply] PARAMS { default: [-cl, 7, -qp, 11, -qn, 8], high: [-cl, 10, -qp, 10, -qn, 6], precise: [-cl, 5, -qp, 14, -qn, 10], } for model in MODELS: for name, flags in PARAMS.items(): drc f{model}.{name}.drc out f{model}.{name}.obj t0 time.time() subprocess.run([./draco_encoder.exe, -i, model, -o, drc] flags, checkTrue) enc_time time.time() - t0 size os.path.getsize(drc) t0 time.time() subprocess.run([./draco_decoder.exe, -i, drc, -o, out], checkTrue) dec_time time.time() - t0 print(f{model} | {name:8s} | {size:8d}B | enc {enc_time:.3f}s | dec {dec_time:.3f}s)这段脚本把三组参数跑一遍输出体积、编码耗时、解码耗时。体积容易看耗时和精度的对比需要配合下一步。6.2 误差不只看文件大小体积小了不代表能直接用。把解码出来的 OBJ 和原始模型同时拖进 MeshLab开启测量工具看 Hausdorff 距离这是网格之间差异的常用度量指标。另外还要检查顶点数和面数是否一致——如果 DRACO 做了拓扑简化面数会发生变化视觉上看不出来但下游程序计算会出错。量化位数每减 1 位理论几何误差翻一倍。所以-qp 10的体积优势往往伴随肉眼可见的棱角模糊。对展示类模型可能无所谓对图纸测量或碰撞检测场景就是灾难。用脚本跑完数据后我会把当时的判定标准写进注释里避免三个月后再调参时忘记当初为什么选了这组数值。6.3 我为什么坚持“先解码再编码”的验证流程这件事吃过亏。早前压缩一个带精细雕刻面的结构件发现-cl 10 -qp 8能把体积压掉 90%当时只看体积就以为成功直接交付。后来合作方反馈模型在某些角度出现明显畸变我才意识到量化位数为 8 时那份模型的位置精度已经被压到了毫米级而需求是 0.1 毫米。从那以后我每次改参数都强制跑一遍回归编码、解码、对比面数、对比 Hausdorff 距离量化位数宁可多留一位也不敢为了几 KB 体积去赌视觉质量。这份便捷的资源省掉了编译时间但调参的验证工时省不得。希望你能把每一步验证做扎实少走我走过的弯路希望帮到你。本文还有配套的精品资源点击获取
返回列表