通用GUI编程技术——图形渲染实战(二十九)——Direct2D架构与资源体系:GPU加速2D渲染入门

news2026/4/11 13:39:34
通用GUI编程技术——图形渲染实战二十九——Direct2D架构与资源体系GPU加速2D渲染入门仓库已经开源喜欢的话点个⭐包含Win32的目前已完成教程力争做一个完备的GUI教程欢迎各位大佬前来参观https://github.com/Charliechen114514/anatomy_guiPS: 笔者马上出差回来要开始更忙了所以相关文章为了确保质量更新频率做调整GUI/Qt的教程会二选一更新嵌入式现代C工程实践和嵌入式Linux也会进行交替的更新确保质量到这里我们已经把 Windows 上 CPU 时代的 2D 图形 API 都过了一遍——从原始的 GDI 到封装更优雅的 GDI。说实话GDI 在功能上已经能满足很多需求了但如果你尝试用它做高频率刷新的动画或者在高 DPI 显示器上绘制复杂场景你会立刻感受到性能瓶颈。GDI 和 GDI 都是 CPU 绘制——每一条线、每一个像素都由 CPU 逐个计算GPU 在旁边闲着看热闹。今天我们要跨入一个全新的领域Direct2D。这是微软在 Windows 7 时代推出的 GPU 加速 2D 渲染 API。它的设计哲学和 GDI 完全不同——所有的绘制操作都由 GPU 执行CPU 只负责下达指令。这意味着你可以轻松实现 60fps 的流畅动画同时保持高质量的抗锯齿渲染。但天下没有免费的午餐GPU 加速带来了新的复杂性资源管理模型变了设备丢失需要处理COM 接口的引用计数得操心。今天我们就来拆解 Direct2D 的架构从初始化到第一次绘制。环境说明操作系统: Windows 10/11Direct2D 需要 Windows 7 SP1 平台更新或更高编译器: MSVC (Visual Studio 2022, v17.x 工具集)目标平台: Win32 原生桌面应用图形库: Direct2D链接d2d1.lib头文件d2d1.h字符集: Unicode⚠️ 注意Direct2D 是基于 COMComponent Object Model的 API。所有接口如ID2D1Factory、ID2D1HwndRenderTarget都是 COM 接口通过引用计数管理生命周期。你在使用完之后必须调用Release()方法释放而不是delete。这一点和 GDI 的 C 类自动析构完全不同。Direct2D 的定位与设计哲学Direct2D 的官方定位是GDI 的现代替代品。但如果你用过 GDI你会发现 Direct2D 的编程模型和 GDI 差异巨大几乎是从零开始学。Direct2D 底层通过 Direct3D 10.1 的 API 与 GPU 通信所有的 2D 绘制操作最终都被转换成 GPU 能理解的三角形和纹理采样操作。这意味着 Direct2D 天然支持硬件加速绘制性能远超 CPU 方案。同时Direct2D 也提供了软件回退WARP — Windows Advanced Rasterization Platform在没有 GPU 或 GPU 驱动异常的环境下仍能正常工作。Direct2D 的设计遵循两个核心原则第一是硬件加速优先所有渲染都通过 GPU 完成第二是高 DPI 感知API 内部使用浮点坐标自动处理 DPI 缩放。资源的两级分类理解 Direct2D 资源管理的关键在于区分两类资源设备无关资源和设备相关资源。设备无关资源不依赖于特定的 GPU 硬件或渲染配置。创建一次可以重复使用。典型的设备无关资源包括ID2D1FactoryDirect2D 的工厂接口用于创建所有其他对象、ID2D1StrokeStyle线条样式、ID2D1Geometry及其子类矩形、椭圆、路径几何体等。这些资源通常在程序启动时创建程序退出时释放。设备相关资源依赖于特定的渲染目标Render Target与 GPU 硬件绑定。渲染目标本身就是最重要的设备相关资源。ID2D1HwndRenderTarget窗口渲染目标、ID2D1Brush画刷包括纯色、渐变、位图画刷、ID2D1Bitmap位图都属于这一类。设备相关资源有一个致命特性当设备丢失时比如 GPU 驱动崩溃恢复、显示设置变更所有设备相关资源都会失效必须全部重建。⚠️ 注意这个设备丢失不是理论上的极端情况。在笔记本外接显示器热插拔、远程桌面连接断开、GPU 驱动更新等场景下都会触发。如果你的程序不处理设备丢失轻则画面消失重则崩溃。我们后面会专门讲怎么处理这个问题。Direct2D 初始化标准骨架让我们从最基础的初始化开始一步步搭建一个完整的 Direct2D 程序。创建 ID2D1FactoryID2D1Factory是 Direct2D 的入口点所有其他 Direct2D 对象都通过它创建。创建方式如下ID2D1Factory*pFactoryNULL;HRESULT hrD2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED,// 单线程模式pFactory);if(FAILED(hr)){// 创建失败处理return;}D2D1CreateFactory的第一个参数指定工厂类型。D2D1_FACTORY_TYPE_SINGLE_THREADED表示你的程序只在一个线程中使用 Direct2D这是最常见的情况性能也最好。D2D1_FACTORY_TYPE_MULTI_THREADED表示多线程使用Direct2D 内部会加锁保护但会带来性能开销。除非你确实需要从多个线程同时调用 Direct2D否则始终用单线程模式。创建 HwndRenderTarget有了工厂之后下一步是创建窗口渲染目标HwndRenderTarget它负责将 GPU 渲染结果呈现到指定的窗口上RECT rc;GetClientRect(hwnd,rc);ID2D1HwndRenderTarget*pRenderTargetNULL;hrpFactory-CreateHwndRenderTarget(D2D1::RenderTargetProperties(),// 默认渲染目标属性D2D1::HwndRenderTargetProperties(hwnd,// 目标窗口句柄D2D1::SizeU(rc.right-rc.left,rc.bottom-rc.top)// 像素尺寸),pRenderTarget);if(FAILED(hr)){// 创建失败处理return;}RenderTargetProperties控制渲染目标的一般属性比如像素格式、DPI 设置、渲染模式等。默认参数RenderTargetProperties()无参版本会使用 32 位 BGRA 格式、系统默认 DPI 和硬件加速渲染。大多数情况下默认就够了。HwndRenderTargetProperties是窗口渲染目标的专用属性需要你提供窗口句柄和初始像素尺寸。这里的尺寸使用像素单位不是逻辑单位。创建画刷在 Direct2D 中所有填充和描边操作都需要画刷Brush。最基本的画刷是纯色画刷ID2D1SolidColorBrush*pBrushNULL;hrpRenderTarget-CreateSolidColorBrush(D2D1::ColorF(D2D1::ColorF::White),// 白色pBrush);D2D1::ColorF是一个辅助类可以用多种方式指定颜色。除了使用预定义的颜色常量如ColorF::White、ColorF::Red你也可以传入 RGB 值// 自定义颜色浅灰蓝色 (R:0.85, G:0.90, B:0.95, Alpha:1.0)pRenderTarget-CreateSolidColorBrush(D2D1::ColorF(0.85f,0.90f,0.95f,1.0f),pBrush);⚠️ 注意Direct2D 的颜色分量范围是 0.0 到 1.0 的浮点数不是 GDI 那种 0-255 的整数。如果你习惯了 GDI 的RGB(255, 128, 0)写法需要手动除以 255 转换。绘制循环BeginDraw / EndDrawDirect2D 的绘制操作必须在BeginDraw和EndDraw之间进行。这是一个硬性要求在BeginDraw之外调用任何绘制方法都会静默失败不报错但也不绘制。voidOnPaint(ID2D1HwndRenderTarget*pRenderTarget,ID2D1SolidColorBrush*pBrush){pRenderTarget-BeginDraw();// 清除背景为深灰色pRenderTarget-Clear(D2D1::ColorF(D2D1::ColorF::DarkSlateGray));// 绘制一个填充的圆角矩形D2D1_ROUNDED_RECT roundedRectD2D1::RoundedRect(D2D1::RectF(50.0f,50.0f,350.0f,200.0f),// 矩形区域10.0f,// X 方向圆角半径10.0f// Y 方向圆角半径);pBrush-SetColor(D2D1::ColorF(0.2f,0.6f,0.9f,1.0f));// 蓝色pRenderTarget-FillRoundedRectangle(roundedRect,pBrush);// 结束绘制HRESULT hrpRenderTarget-EndDraw();if(hrD2DERR_RECREATE_TARGET){// 设备丢失需要重建所有设备相关资源// 后面会详细讲解}}BeginDraw会标记渲染目标的内部状态为正在绘制EndDraw会提交所有绘制命令并呈现结果。如果在BeginDraw和EndDraw之间发生了错误EndDraw会返回对应的HRESULT。这里有一个非常重要的返回值需要处理D2DERR_RECREATE_TARGET。这个返回值表示渲染目标关联的 GPU 设备已经丢失比如驱动崩溃后恢复当前的渲染目标和所有设备相关资源画刷、位图等都已失效。你必须在收到这个错误后重建所有设备相关资源。处理窗口大小变化当窗口大小改变时你需要调用Resize方法通知渲染目标更新其后备缓冲区的大小caseWM_SIZE:{if(pRenderTarget!NULL){UINT widthLOWORD(lParam);UINT heightHIWORD(lParam);pRenderTarget-Resize(D2D1::SizeU(width,height));InvalidateRect(hwnd,NULL,FALSE);// 触发重绘}return0;}如果你不调用Resize渲染目标的后备缓冲区大小不会自动跟随窗口变化结果就是窗口变大后只有一部分区域有内容或者窗口变小后渲染目标浪费内存。设备丢失的完整处理模式现在我们来处理D2DERR_RECREATE_TARGET。标准的处理模式是在EndDraw之后检查返回值如果收到重建信号就释放所有设备相关资源并重建// 全局变量ID2D1Factory*g_pFactoryNULL;ID2D1HwndRenderTarget*g_pRenderTargetNULL;ID2D1SolidColorBrush*g_pBrushNULL;voidCreateDeviceResources(HWND hwnd){if(g_pRenderTarget!NULL)return;// 已存在跳过RECT rc;GetClientRect(hwnd,rc);HRESULT hrg_pFactory-CreateHwndRenderTarget(D2D1::RenderTargetProperties(),D2D1::HwndRenderTargetProperties(hwnd,D2D1::SizeU(rc.right-rc.left,rc.bottom-rc.top)),g_pRenderTarget);if(FAILED(hr))return;// 创建画刷等设备相关资源g_pRenderTarget-CreateSolidColorBrush(D2D1::ColorF(D2D1::ColorF::White),g_pBrush);}voidDiscardDeviceResources(){// 按创建的逆序释放SafeRelease(g_pBrush);SafeRelease(g_pRenderTarget);}voidOnPaint(HWND hwnd){CreateDeviceResources(hwnd);if(g_pRenderTargetNULL)return;g_pRenderTarget-BeginDraw();g_pRenderTarget-Clear(D2D1::ColorF(0.15f,0.15f,0.15f,1.0f));// ... 绘制代码 ...HRESULT hrg_pRenderTarget-EndDraw();if(hrD2DERR_RECREATE_TARGET){DiscardDeviceResources();InvalidateRect(hwnd,NULL,FALSE);// 立即触发重绘以重建资源}}// SafeRelease 辅助函数templateclassTvoidSafeRelease(T**ppT){if(*ppT){(*ppT)-Release();*ppTNULL;}}这个模式的核心思想是延迟创建 按需重建。CreateDeviceResources在每次OnPaint时检查资源是否存在不存在才创建。DiscardDeviceResources在设备丢失时释放所有设备相关资源。下次OnPaint时CreateDeviceResources发现资源为NULL会自动重建。注意ID2D1Factory是设备无关资源不需要在设备丢失时重建。完整的最小 Direct2D 程序下面是一个可以直接编译运行的完整示例#includewindows.h#included2d1.h#includecmath#pragmacomment(lib,d2d1.lib)templateclassTvoidSafeRelease(T**ppT){if(*ppT){(*ppT)-Release();*ppTNULL;}}ID2D1Factory*g_pFactoryNULL;ID2D1HwndRenderTarget*g_pRTNULL;ID2D1SolidColorBrush*g_pBrushNULL;floatg_angle0.0f;voidCreateDeviceResources(HWND hwnd){if(g_pRT)return;RECT rc;GetClientRect(hwnd,rc);g_pFactory-CreateHwndRenderTarget(D2D1::RenderTargetProperties(),D2D1::HwndRenderTargetProperties(hwnd,D2D1::SizeU(rc.right,rc.bottom)),g_pRT);if(g_pRT)g_pRT-CreateSolidColorBrush(D2D1::ColorF(D2D1::ColorF::White),g_pBrush);}voidDiscardDeviceResources(){SafeRelease(g_pBrush);SafeRelease(g_pRT);}voidOnPaint(HWND hwnd){CreateDeviceResources(hwnd);if(!g_pRT)return;g_pRT-BeginDraw();g_pRT-Clear(D2D1::ColorF(0.1f,0.1f,0.15f,1.0f));RECT rc;GetClientRect(hwnd,rc);floatcx(rc.right-rc.left)/2.0f;floatcy(rc.bottom-rc.top)/2.0f;floatr80.0f;// 绘制旋转的三角形D2D1_POINT_2F points[3];for(inti0;i3;i){floatag_anglei*(2.0f*3.14159f/3.0f);points[i]D2D1::Point2F(cxr*cosf(a),cyr*sinf(a));}g_pBrush-SetColor(D2D1::ColorF(0.3f,0.7f,1.0f,0.8f));g_pRT-DrawLine(points[0],points[1],g_pBrush,3.0f);g_pRT-DrawLine(points[1],points[2],g_pBrush,3.0f);g_pRT-DrawLine(points[2],points[0],g_pBrush,3.0f);HRESULT hrg_pRT-EndDraw();if(hrD2DERR_RECREATE_TARGET){DiscardDeviceResources();InvalidateRect(hwnd,NULL,FALSE);}}LRESULT CALLBACKWndProc(HWND hwnd,UINT uMsg,WPARAM wParam,LPARAM lParam){switch(uMsg){caseWM_PAINT:OnPaint(hwnd);ValidateRect(hwnd,NULL);return0;caseWM_TIMER:g_angle0.05f;InvalidateRect(hwnd,NULL,FALSE);return0;caseWM_SIZE:if(g_pRT){g_pRT-Resize(D2D1::SizeU(LOWORD(lParam),HIWORD(lParam)));InvalidateRect(hwnd,NULL,FALSE);}return0;caseWM_DESTROY:DiscardDeviceResources();SafeRelease(g_pFactory);KillTimer(hwnd,1);PostQuitMessage(0);return0;}returnDefWindowProc(hwnd,uMsg,wParam,lParam);}intWINAPIwWinMain(HINSTANCE hInstance,HINSTANCE,PWSTR,intnCmdShow){D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED,g_pFactory);constwchar_tcls[]LD2DDemo;WNDCLASS wc{};wc.lpfnWndProcWndProc;wc.hInstancehInstance;wc.lpszClassNamecls;wc.hCursorLoadCursor(NULL,IDC_ARROW);RegisterClass(wc);HWND hwndCreateWindow(cls,LDirect2D 旋转三角形,WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,CW_USEDEFAULT,600,500,NULL,NULL,hInstance,NULL);ShowWindow(hwnd,nCmdShow);SetTimer(hwnd,1,16,NULL);// ~60fpsMSG msg;while(GetMessage(msg,NULL,0,0)){TranslateMessage(msg);DispatchMessage(msg);}return0;}常见问题与调试问题1D2D1CreateFactory 返回 E_FAIL这通常意味着系统中没有安装 Direct2D 运行时。Direct2D 需要 Windows 7 SP1 平台更新或更高版本。在 Windows Vista 或未打补丁的 Windows 7 上D2D1CreateFactory会失败。检查你的目标系统版本要求。问题2BeginDraw / EndDraw 外调用绘制方法这是一个静默失败的场景——不会报错不会崩溃但画面上什么都不会出现。如果你发现DrawRectangle、FillEllipse等方法不工作首先检查你是在BeginDraw和EndDraw之间调用它们的。问题3画面闪烁如果你在WM_PAINT处理中既用 GDIBeginPaint/EndPaint又用 Direct2D可能会出现闪烁。因为 GDI 的BeginPaint会擦除背景而 Direct2D 的BeginDraw不会。解决办法是只使用 Direct2D 绘制或者处理WM_ERASEBKGND返回TRUE阻止背景擦除。总结到这里我们已经把 Direct2D 的基础架构梳理清楚了。核心概念是资源的两级分类设备无关 vs 设备相关、BeginDraw/EndDraw的绘制框架、以及D2DERR_RECREATE_TARGET的设备丢失处理。这些是你使用 Direct2D 时每天都在打交道的模式。和 GDI 相比Direct2D 的初始化确实更复杂——需要创建工厂、创建渲染目标、创建画刷而且还要处理 COM 引用计数和设备丢失。但这些都是一次性的模板代码复制粘贴即可。真正的好处在于从今天开始你所有的 2D 绘制都由 GPU 加速了。下一步我们要深入 Direct2D 的几何体系统。Direct2D 提供了比 GDI 丰富得多的几何体类型——从简单的矩形和椭圆到贝塞尔曲线和布尔运算组合的复杂路径。更重要的是Direct2D 的几何体支持精确的命中测试这是构建交互式图形应用的基础。练习用 Direct2D 重写之前 GDI 的双缓冲动画示例弹跳球对比两者的代码结构和运行性能。实现一个渐变背景窗口使用ID2D1LinearGradientBrush从窗口顶部到底部绘制蓝色到紫色的渐变。处理WM_DPICHANGED消息在 DPI 变化时正确调整渲染目标的大小和画刷参数。实现设备丢失的自动恢复在EndDraw返回D2DERR_RECREATE_TARGET后重建所有资源并重绘确保用户看不到任何闪烁或中断。参考资料:D2D1CreateFactory function - Microsoft LearnID2D1HwndRenderTarget interface - Microsoft LearnID2D1RenderTarget::BeginDraw - Microsoft LearnID2D1SolidColorBrush - Microsoft LearnHandling Device Loss in Direct2D - Microsoft LearnDirect2D and GDI Interoperability Overview - Microsoft Learn相关阅读通用GUI编程技术——图形渲染实战二十五——Alpha混合与透明效果分层窗口实战 - 相似度 100%通用GUI编程技术——图形渲染实战二十六——GDI与GDI架构差异抗锯齿与渐变 - 相似度 100%通用GUI编程技术——Win32 原生编程实战二十二——GDI 位图操作BitBlt、StretchBlt 与图像处理 - 相似度 80%

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2506319.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

SpringBoot-17-MyBatis动态SQL标签之常用标签

文章目录 1 代码1.1 实体User.java1.2 接口UserMapper.java1.3 映射UserMapper.xml1.3.1 标签if1.3.2 标签if和where1.3.3 标签choose和when和otherwise1.4 UserController.java2 常用动态SQL标签2.1 标签set2.1.1 UserMapper.java2.1.2 UserMapper.xml2.1.3 UserController.ja…

wordpress后台更新后 前端没变化的解决方法

使用siteground主机的wordpress网站,会出现更新了网站内容和修改了php模板文件、js文件、css文件、图片文件后,网站没有变化的情况。 不熟悉siteground主机的新手,遇到这个问题,就很抓狂,明明是哪都没操作错误&#x…

网络编程(Modbus进阶)

思维导图 Modbus RTU(先学一点理论) 概念 Modbus RTU 是工业自动化领域 最广泛应用的串行通信协议,由 Modicon 公司(现施耐德电气)于 1979 年推出。它以 高效率、强健性、易实现的特点成为工业控制系统的通信标准。 包…

UE5 学习系列(二)用户操作界面及介绍

这篇博客是 UE5 学习系列博客的第二篇,在第一篇的基础上展开这篇内容。博客参考的 B 站视频资料和第一篇的链接如下: 【Note】:如果你已经完成安装等操作,可以只执行第一篇博客中 2. 新建一个空白游戏项目 章节操作,重…

IDEA运行Tomcat出现乱码问题解决汇总

最近正值期末周,有很多同学在写期末Java web作业时,运行tomcat出现乱码问题,经过多次解决与研究,我做了如下整理: 原因: IDEA本身编码与tomcat的编码与Windows编码不同导致,Windows 系统控制台…

利用最小二乘法找圆心和半径

#include <iostream> #include <vector> #include <cmath> #include <Eigen/Dense> // 需安装Eigen库用于矩阵运算 // 定义点结构 struct Point { double x, y; Point(double x_, double y_) : x(x_), y(y_) {} }; // 最小二乘法求圆心和半径 …

使用docker在3台服务器上搭建基于redis 6.x的一主两从三台均是哨兵模式

一、环境及版本说明 如果服务器已经安装了docker,则忽略此步骤,如果没有安装,则可以按照一下方式安装: 1. 在线安装(有互联网环境): 请看我这篇文章 传送阵>> 点我查看 2. 离线安装(内网环境):请看我这篇文章 传送阵>> 点我查看 说明&#xff1a;假设每台服务器已…

XML Group端口详解

在XML数据映射过程中&#xff0c;经常需要对数据进行分组聚合操作。例如&#xff0c;当处理包含多个物料明细的XML文件时&#xff0c;可能需要将相同物料号的明细归为一组&#xff0c;或对相同物料号的数量进行求和计算。传统实现方式通常需要编写脚本代码&#xff0c;增加了开…

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器的上位机配置操作说明

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器专为工业环境精心打造&#xff0c;完美适配AGV和无人叉车。同时&#xff0c;集成以太网与语音合成技术&#xff0c;为各类高级系统&#xff08;如MES、调度系统、库位管理、立库等&#xff09;提供高效便捷的语音交互体验。 L…

(LeetCode 每日一题) 3442. 奇偶频次间的最大差值 I (哈希、字符串)

题目&#xff1a;3442. 奇偶频次间的最大差值 I 思路 &#xff1a;哈希&#xff0c;时间复杂度0(n)。 用哈希表来记录每个字符串中字符的分布情况&#xff0c;哈希表这里用数组即可实现。 C版本&#xff1a; class Solution { public:int maxDifference(string s) {int a[26]…

【大模型RAG】拍照搜题技术架构速览:三层管道、两级检索、兜底大模型

摘要 拍照搜题系统采用“三层管道&#xff08;多模态 OCR → 语义检索 → 答案渲染&#xff09;、两级检索&#xff08;倒排 BM25 向量 HNSW&#xff09;并以大语言模型兜底”的整体框架&#xff1a; 多模态 OCR 层 将题目图片经过超分、去噪、倾斜校正后&#xff0c;分别用…

【Axure高保真原型】引导弹窗

今天和大家中分享引导弹窗的原型模板&#xff0c;载入页面后&#xff0c;会显示引导弹窗&#xff0c;适用于引导用户使用页面&#xff0c;点击完成后&#xff0c;会显示下一个引导弹窗&#xff0c;直至最后一个引导弹窗完成后进入首页。具体效果可以点击下方视频观看或打开下方…

接口测试中缓存处理策略

在接口测试中&#xff0c;缓存处理策略是一个关键环节&#xff0c;直接影响测试结果的准确性和可靠性。合理的缓存处理策略能够确保测试环境的一致性&#xff0c;避免因缓存数据导致的测试偏差。以下是接口测试中常见的缓存处理策略及其详细说明&#xff1a; 一、缓存处理的核…

龙虎榜——20250610

上证指数放量收阴线&#xff0c;个股多数下跌&#xff0c;盘中受消息影响大幅波动。 深证指数放量收阴线形成顶分型&#xff0c;指数短线有调整的需求&#xff0c;大概需要一两天。 2025年6月10日龙虎榜行业方向分析 1. 金融科技 代表标的&#xff1a;御银股份、雄帝科技 驱动…

观成科技:隐蔽隧道工具Ligolo-ng加密流量分析

1.工具介绍 Ligolo-ng是一款由go编写的高效隧道工具&#xff0c;该工具基于TUN接口实现其功能&#xff0c;利用反向TCP/TLS连接建立一条隐蔽的通信信道&#xff0c;支持使用Let’s Encrypt自动生成证书。Ligolo-ng的通信隐蔽性体现在其支持多种连接方式&#xff0c;适应复杂网…

铭豹扩展坞 USB转网口 突然无法识别解决方法

当 USB 转网口扩展坞在一台笔记本上无法识别,但在其他电脑上正常工作时,问题通常出在笔记本自身或其与扩展坞的兼容性上。以下是系统化的定位思路和排查步骤,帮助你快速找到故障原因: 背景: 一个M-pard(铭豹)扩展坞的网卡突然无法识别了,扩展出来的三个USB接口正常。…

未来机器人的大脑:如何用神经网络模拟器实现更智能的决策?

编辑&#xff1a;陈萍萍的公主一点人工一点智能 未来机器人的大脑&#xff1a;如何用神经网络模拟器实现更智能的决策&#xff1f;RWM通过双自回归机制有效解决了复合误差、部分可观测性和随机动力学等关键挑战&#xff0c;在不依赖领域特定归纳偏见的条件下实现了卓越的预测准…

Linux应用开发之网络套接字编程(实例篇)

服务端与客户端单连接 服务端代码 #include <sys/socket.h> #include <sys/types.h> #include <netinet/in.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <arpa/inet.h> #include <pthread.h> …

华为云AI开发平台ModelArts

华为云ModelArts&#xff1a;重塑AI开发流程的“智能引擎”与“创新加速器”&#xff01; 在人工智能浪潮席卷全球的2025年&#xff0c;企业拥抱AI的意愿空前高涨&#xff0c;但技术门槛高、流程复杂、资源投入巨大的现实&#xff0c;却让许多创新构想止步于实验室。数据科学家…

深度学习在微纳光子学中的应用

深度学习在微纳光子学中的主要应用方向 深度学习与微纳光子学的结合主要集中在以下几个方向&#xff1a; 逆向设计 通过神经网络快速预测微纳结构的光学响应&#xff0c;替代传统耗时的数值模拟方法。例如设计超表面、光子晶体等结构。 特征提取与优化 从复杂的光学数据中自…