(一)before initialization of D3D(初始化D3D之前你需要了解的D3D基础知识)

news2024/11/24 16:31:53

什么是D3D?

D3D全称Direct X 3D,即一组API可以用来针对GPU编程,不过他最主要的作用是用来渲染(不过现在也有很多其他应用比如d3d11va[Direct X 3D 11 Video API]用来进行硬件加速解码)

Tips:Direct X 3D主要用来渲染,既然我们说到可以针对GPU编程了,当然不只是渲染的工作可以交给GPU做,一些比较繁杂的计算比如排个两亿个数的序我们仍然可以交给GPU完成,所以推出一项技术就叫做GPGPU(General-purpose computing on graphics processing units)通用GPU计算,由此而衍生的技术便是CUDA,OpenCL等技术

此处只是给小伙伴扩充一下知识面,本文并不会涉及到这些GPGPU技术

有些小伙伴可能对渲染没什么概念,我举一个例子,比如你的显示屏是1920*1080的分辨率,那么你只需要指定好1920*1080个像素点中的每一个像素点的颜色,即可以让显示器帮你显示一张图片

那么问题来了 我刚刚提到的1920*1080个像素点的颜色应该怎么计算出来呢?

答案就是由GPU或者CPU计算得出

比如你现在正在使用一个显示屏看我的文章,你的屏幕上的每一个像素点就是由你的CPU或者GPU算出的(非游戏等需要高性能渲染的地方,通常是用CPU算出每一个像素点的颜色)

那我们平常编写的代码比如你写的C++代码是不能够直接控制GPU的,因为你编译好的可执行文件里存放的全是对应CPU指令集架构的指令,而不是GPU的指令,所以GPU并不能执行你的C++代码

所以我们需要一个桥梁啊,可以让我们的代码能够直接控制GPU, 让我们能够把数据和控制这些数据的操作上传到GPU给我们渲染,所以微软和各家显卡厂商合作一起推出了Windows上的渲染API Direct X 3D,并且规定了很多渲染过程中会使用到的东西 比如纹理,交换链,缓冲区,命令队列等等渲染图像会使用到的东西

当然也不止微软在做这个渲染API,常用的渲染API还有OpenGL,Vulkan等等

那么问题就来到了 Direct X 3D中已经规定好的东西有哪些东西呢?

纹理(texture)

纹理又可以分为2D 纹理和3D 纹理,如果读者接触过c++ 那么可以直接把2D 纹理当做一个二维数组,如下代码所示

#define DATATYPE int
vector<vector<DATATYPE>> 2D_texture;

而3D 纹理则是如下形式

#define DATATYPE int
vector<vector<vector<DATATYPE>>> 3D_texture;

 Tips:任何颜色都可以通过三基色(RGB,R[红色],G[绿色],B[蓝色])混合得到,所以对于任意像素点,只要我们知道了他的红色究竟有多红,绿色究竟有多绿,蓝色究竟有多蓝,即可以组合成世界上所有的颜色.

基于2D 纹理的这种二维数组形式,所以我们经常用2D 纹理来存储一张图片,比如一张图片是1920*1080的分辨率,每个像素点是由RGBA来构成那么2D 纹理便可以表示为如下这种格式

struct pixel_color
{
    unsigned char RED;//0-255 数字越大表示越红
    unsigned char GREEN;
    unsigned char BLUE;
    unsigned char ALPHA;//数字越大表示越不透明
}
#define DATATYPE pixel_color
vector<vector<DATATYPE>> 2D_texture(1920,vector<DATATYPE>(1080));

那么对于任意2D_texture[i][j]中的元素便是表示位于(i,j)这个点的像素颜色是什么

对于3D纹理也是一样的原理,读者可以自由扩展

那么问题来了 D3D中纹理支持的DATATYPE(也就是我们上文中二维数组可以装载的数据类型)有哪些呢?

typedef enum DXGI_FORMAT
{
    DXGI_FORMAT_UNKNOWN	                                = 0,
    DXGI_FORMAT_R32G32B32A32_TYPELESS                   = 1,
    DXGI_FORMAT_R32G32B32A32_FLOAT                      = 2,
    DXGI_FORMAT_R32G32B32A32_UINT                       = 3,
    DXGI_FORMAT_R32G32B32A32_SINT                       = 4,
    DXGI_FORMAT_R32G32B32_TYPELESS                      = 5,
    DXGI_FORMAT_R32G32B32_FLOAT                         = 6,
    DXGI_FORMAT_R32G32B32_UINT                          = 7,
    DXGI_FORMAT_R32G32B32_SINT                          = 8,
    DXGI_FORMAT_R16G16B16A16_TYPELESS                   = 9,
    DXGI_FORMAT_R16G16B16A16_FLOAT                      = 10,
    DXGI_FORMAT_R16G16B16A16_UNORM                      = 11,
    DXGI_FORMAT_R16G16B16A16_UINT                       = 12,
    DXGI_FORMAT_R16G16B16A16_SNORM                      = 13,
    DXGI_FORMAT_R16G16B16A16_SINT                       = 14,
    DXGI_FORMAT_R32G32_TYPELESS                         = 15,
    DXGI_FORMAT_R32G32_FLOAT                            = 16,
    DXGI_FORMAT_R32G32_UINT                             = 17,
    DXGI_FORMAT_R32G32_SINT                             = 18,
    DXGI_FORMAT_R32G8X24_TYPELESS                       = 19,
    DXGI_FORMAT_D32_FLOAT_S8X24_UINT                    = 20,
    DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS                = 21,
    DXGI_FORMAT_X32_TYPELESS_G8X24_UINT                 = 22,
    DXGI_FORMAT_R10G10B10A2_TYPELESS                    = 23,
    DXGI_FORMAT_R10G10B10A2_UNORM                       = 24,
    DXGI_FORMAT_R10G10B10A2_UINT                        = 25,
    DXGI_FORMAT_R11G11B10_FLOAT                         = 26,
    DXGI_FORMAT_R8G8B8A8_TYPELESS                       = 27,
    DXGI_FORMAT_R8G8B8A8_UNORM                          = 28,
    DXGI_FORMAT_R8G8B8A8_UNORM_SRGB                     = 29,
    DXGI_FORMAT_R8G8B8A8_UINT                           = 30,
    DXGI_FORMAT_R8G8B8A8_SNORM                          = 31,
    DXGI_FORMAT_R8G8B8A8_SINT                           = 32,
    DXGI_FORMAT_R16G16_TYPELESS                         = 33,
    DXGI_FORMAT_R16G16_FLOAT                            = 34,
    DXGI_FORMAT_R16G16_UNORM                            = 35,
    DXGI_FORMAT_R16G16_UINT                             = 36,
    DXGI_FORMAT_R16G16_SNORM                            = 37,
    DXGI_FORMAT_R16G16_SINT                             = 38,
    DXGI_FORMAT_R32_TYPELESS                            = 39,
    DXGI_FORMAT_D32_FLOAT                               = 40,
    DXGI_FORMAT_R32_FLOAT                               = 41,
    DXGI_FORMAT_R32_UINT                                = 42,
    DXGI_FORMAT_R32_SINT                                = 43,
    DXGI_FORMAT_R24G8_TYPELESS                          = 44,
    DXGI_FORMAT_D24_UNORM_S8_UINT                       = 45,
    DXGI_FORMAT_R24_UNORM_X8_TYPELESS                   = 46,
    DXGI_FORMAT_X24_TYPELESS_G8_UINT                    = 47,
    DXGI_FORMAT_R8G8_TYPELESS                           = 48,
    DXGI_FORMAT_R8G8_UNORM                              = 49,
    DXGI_FORMAT_R8G8_UINT                               = 50,
    DXGI_FORMAT_R8G8_SNORM                              = 51,
    DXGI_FORMAT_R8G8_SINT                               = 52,
    DXGI_FORMAT_R16_TYPELESS                            = 53,
    DXGI_FORMAT_R16_FLOAT                               = 54,
    DXGI_FORMAT_D16_UNORM                               = 55,
    DXGI_FORMAT_R16_UNORM                               = 56,
    DXGI_FORMAT_R16_UINT                                = 57,
    DXGI_FORMAT_R16_SNORM                               = 58,
    DXGI_FORMAT_R16_SINT                                = 59,
    DXGI_FORMAT_R8_TYPELESS                             = 60,
    DXGI_FORMAT_R8_UNORM                                = 61,
    DXGI_FORMAT_R8_UINT                                 = 62,
    DXGI_FORMAT_R8_SNORM                                = 63,
    DXGI_FORMAT_R8_SINT                                 = 64,
    DXGI_FORMAT_A8_UNORM                                = 65,
    DXGI_FORMAT_R1_UNORM                                = 66,
    DXGI_FORMAT_R9G9B9E5_SHAREDEXP                      = 67,
    DXGI_FORMAT_R8G8_B8G8_UNORM                         = 68,
    DXGI_FORMAT_G8R8_G8B8_UNORM                         = 69,
    DXGI_FORMAT_BC1_TYPELESS                            = 70,
    DXGI_FORMAT_BC1_UNORM                               = 71,
    DXGI_FORMAT_BC1_UNORM_SRGB                          = 72,
    DXGI_FORMAT_BC2_TYPELESS                            = 73,
    DXGI_FORMAT_BC2_UNORM                               = 74,
    DXGI_FORMAT_BC2_UNORM_SRGB                          = 75,
    DXGI_FORMAT_BC3_TYPELESS                            = 76,
    DXGI_FORMAT_BC3_UNORM                               = 77,
    DXGI_FORMAT_BC3_UNORM_SRGB                          = 78,
    DXGI_FORMAT_BC4_TYPELESS                            = 79,
    DXGI_FORMAT_BC4_UNORM                               = 80,
    DXGI_FORMAT_BC4_SNORM                               = 81,
    DXGI_FORMAT_BC5_TYPELESS                            = 82,
    DXGI_FORMAT_BC5_UNORM                               = 83,
    DXGI_FORMAT_BC5_SNORM                               = 84,
    DXGI_FORMAT_B5G6R5_UNORM                            = 85,
    DXGI_FORMAT_B5G5R5A1_UNORM                          = 86,
    DXGI_FORMAT_B8G8R8A8_UNORM                          = 87,
    DXGI_FORMAT_B8G8R8X8_UNORM                          = 88,
    DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM              = 89,
    DXGI_FORMAT_B8G8R8A8_TYPELESS                       = 90,
    DXGI_FORMAT_B8G8R8A8_UNORM_SRGB                     = 91,
    DXGI_FORMAT_B8G8R8X8_TYPELESS                       = 92,
    DXGI_FORMAT_B8G8R8X8_UNORM_SRGB                     = 93,
    DXGI_FORMAT_BC6H_TYPELESS                           = 94,
    DXGI_FORMAT_BC6H_UF16                               = 95,
    DXGI_FORMAT_BC6H_SF16                               = 96,
    DXGI_FORMAT_BC7_TYPELESS                            = 97,
    DXGI_FORMAT_BC7_UNORM                               = 98,
    DXGI_FORMAT_BC7_UNORM_SRGB                          = 99,
    DXGI_FORMAT_AYUV                                    = 100,
    DXGI_FORMAT_Y410                                    = 101,
    DXGI_FORMAT_Y416                                    = 102,
    DXGI_FORMAT_NV12                                    = 103,
    DXGI_FORMAT_P010                                    = 104,
    DXGI_FORMAT_P016                                    = 105,
    DXGI_FORMAT_420_OPAQUE                              = 106,
    DXGI_FORMAT_YUY2                                    = 107,
    DXGI_FORMAT_Y210                                    = 108,
    DXGI_FORMAT_Y216                                    = 109,
    DXGI_FORMAT_NV11                                    = 110,
    DXGI_FORMAT_AI44                                    = 111,
    DXGI_FORMAT_IA44                                    = 112,
    DXGI_FORMAT_P8                                      = 113,
    DXGI_FORMAT_A8P8                                    = 114,
    DXGI_FORMAT_B4G4R4A4_UNORM                          = 115,

    DXGI_FORMAT_P208                                    = 130,
    DXGI_FORMAT_V208                                    = 131,
    DXGI_FORMAT_V408                                    = 132,


    DXGI_FORMAT_SAMPLER_FEEDBACK_MIN_MIP_OPAQUE         = 189,
    DXGI_FORMAT_SAMPLER_FEEDBACK_MIP_REGION_USED_OPAQUE = 190,


    DXGI_FORMAT_FORCE_UINT                  = 0xffffffff
} DXGI_FORMAT;

常用的DATATYPE有这些:

 交换链(swap chain)和缓冲区置换(也叫页面翻转或presenting)

 上文我们说到,渲染所做的事情就是确定我们1080P屏幕上的每一个像素点的颜色,那么如果把我们的屏幕需要的数据比作一个2D 纹理(上文我们说到2D纹理其实就是2维数组)

1080P也就是分辨率为1920*1080

struct pixel_color
{
    unsigned char RED;//0-255 数字越大表示越红
    unsigned char GREEN;
    unsigned char BLUE;
    unsigned char ALPHA;//数字越大表示越不透明
}
#define DATATYPE pixel_color
vector<vector<DATATYPE>> screen_2D_texture(1920,vector<DATATYPE>(1080));

那么我们便是要填充screen_2D_texture这个数组,把他填充满,然后交给显示器就行了,显示器就可以显示一张图片给用户看

那么问题就来到了 当我们把screen_2D_texture这个数组交给显示器的时候,我们是不是也应该继续填充下一个screen_2D_texture,这样才能继续显示下一帧,问题就在于screen_2D_texture这个数组目前是显示屏要获取资源的数组,我们总不能直接把下一帧的数组又写进同一个数组吧?如果写进同一个数组,那么显示屏在读,GPU在写,那么显示屏显示的图片不就乱码了嘛?

所以我们需要多个screen_2D_texture,当数组1交给显示器读的时候,我们只需要把下一帧写进数组2即可,当数组1被读完后,我们把数组2交给显示器读,我们继续把下一帧写进数组1,那么这样交叉的读写便形成了交换链的概念
上文中的技术可以用这张图片表示:

 其中的前台缓冲区便是数组1,后台缓冲区便是数组2,而这种交换的操作,我们又叫他页面翻转或者是presenting(呈现)

使用两个数组 我们便叫做双重缓冲 如果使用三个数组 我们便叫做三重缓冲

深度缓冲(depth buffer)

在d3d渲染流程中,我们最主要的工作就是把三维场景里的所有数据变成我们刚刚提到的后台缓冲区里的数据  也就是把三维物体渲染到二维平面上来 并且确定他渲染到屏幕上之后 对应像素点的颜色

 比如上图中的观察窗口 观察窗口中的像素数据便是我们需要的二维平面的数据 我们从观察点出发

关于观察点这些内容是计算机图形学中的内容,如果想详细了解 请移步至:

GAMES101-现代计算机图形学入门-闫令琪_哔哩哔哩_bilibili

如果读者玩过第一人称游戏就会知道 你的观察点就是从人物的头部进行观察

而第三人称游戏则是从人物背后的天空进行观察

如现代游戏中两种视角的不同(第一人称,第三人称) 仅仅只是因为观察点发生了变化,但是三维空间中的所有三维物体本身并不会发生变化

 现在我们继续回到这幅图中,因为我们从目前的观察点进行观察 会发生什么情况呢 球体上的P1点 圆锥体的P2点 圆柱体的P3点均想把自己的颜色渲染到真正的屏幕数据 P点上,那么我们如何知道究竟应该取P1的颜色还是P2的颜色还是P3的颜色呢?

可能有些小伙伴会说 你直接看谁离的近不就完事了嘛?

计算机确实是取最近的点 但是记住 计算机可没有人的眼睛 他可不能看出三维空间中哪一个三维物体离他近 只能你计算出每个物体的深度后再告诉他才行

 但是目前问题就来了 我们看侧面图 并且给出三个物体的深度d1 d2 d3 

这个时候,当你告诉计算机 d1 d2 d3后 计算机当然可以立马得出是P1点的颜色应该被采用 但是问题就在于 在渲染这三个三维物体的时候 并不是一次性就全部渲染到三维空间中 而是一个物体一个物体的渲染 比如先渲染球,再渲染圆锥体,再渲染圆柱体

那这个时候 你是不是就需要一个记录当前像素点的最近深度是多少? 我举一个例子

如果你是先渲染圆锥体 然后圆柱体 然后球体

那么渲染圆锥的时候 P点的目前距离最近的深度就应该是d2 再渲染圆柱的时候 因为d3大于d2所以P3点不会被渲染到P点上 轮到球体的时候 d1<d2 那么P1点可以绘制到P点上 并且更新最小深度值为d1

这个过程我们叫做深度测试

从管擦点出发 我们能够观察到的深度值范围为0-1

 对于1平面 他的深度便是0 对于2平面 他的深度便是1

所以现在我们推导一下先渲染圆柱体 再渲染球体 最后渲染圆锥体的流程来加深我们的记忆

操作步骤P的值     目前最小的深度值min_d=1步骤描述
绘制圆柱体P3d3因为d3<1.0=min_d,深度测试通过,更新P,更新min_d=d3
绘制球体P1d1因为d1<min_d=d3,深度测试通过,更新P,更新min_d=d1
绘制圆柱体P1d1因为d2>min_d=d1,深度测试不通过,不更新
最终确定P值P1d1交给显示器渲染

所以我们的深度缓冲也是一块2D 纹理,并且其中的元素应该和我们的后台缓冲区一一对应

比如screen_2D_texture[i][j]就应该对应depth_2D_texture[i][j] 

当我们需要去取得(i,j)像素点目前的最小深度的时候,我们直接去depth_2Dtexture[i][j]中获取即可

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

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

相关文章

国考省考行测:数量关系,牛吃草问题,比例问题

国考省考行测&#xff1a;数量关系&#xff0c;牛吃草问题 2022找工作是学历、能力和运气的超强结合体! 公务员特招重点就是专业技能&#xff0c;附带行测和申论&#xff0c;而常规国考省考最重要的还是申论和行测&#xff0c;所以大家认真准备吧&#xff0c;我讲一起屡屡申论…

〖Python网络爬虫实战㉘〗- Selenium案例实战(二)

订阅&#xff1a;新手可以订阅我的其他专栏。免费阶段订阅量1000 python项目实战 Python编程基础教程系列&#xff08;零基础小白搬砖逆袭) 说明&#xff1a;本专栏持续更新中&#xff0c;目前专栏免费订阅&#xff0c;在转为付费专栏前订阅本专栏的&#xff0c;可以免费订阅付…

图神经网络(处理点云)PPFNet的实现

文章说明&#xff1a; 1)参考资料&#xff1a;PYG官方文档。超链。 2)博主水平不高&#xff0c;如有错误还望批评指正。 3)我在百度网盘上传了这篇文章的jupyter notebook和有关文献。超链。提取码8848。 文章目录 前言文献阅读代码实操历史遗留问题 前言 本篇文章接上一篇文章…

今年的面试难度,我给跪了……

大家好&#xff0c;最近有不少小伙伴在后台留言&#xff0c;又得准备面试了&#xff0c;不知道从何下手&#xff01; 不论是跳槽涨薪&#xff0c;还是学习提升&#xff01;先给自己定一个小目标&#xff0c;然后再朝着目标去努力就完事儿了&#xff01; 为了帮大家节约时间&a…

【STM32G431RBTx】备战蓝桥杯嵌入式→决赛试题→第七届

文章目录 前言一、题目二、模块初始化三、代码实现interrupt.h:interrupt.h:main.h:main.h: 四、完成效果五、总结 前言 无 一、题目 二、模块初始化 1.LCD这里不用配置&#xff0c;直接使用提供的资源包就行 2.ADC:开启ADCsingle-ended 3.LED:开启PC8-15,PD2输出模式就行了…

手撕代码——同步FIFO

手撕代码——同步FIFO 一、FIFO原理与设计二、完整代码与仿真结果三、仿真结果 一、FIFO原理与设计 查看Xilinx官方FIFO IP核&#xff0c;其主要的信号有时钟信号、写端口信号、读端口信号&#xff0c;其中&#xff0c;写端口信号包括写满信号full、写使能信号wr_en、写数据输入…

[元带你学: eMMC完全解读 7] eMMC 设备与系统概述

依JEDEC eMMC 5.1及经验辛苦整理,付费内容,禁止转载。 所在专栏 《元带你学: eMMC完全解读》 前言 全文3600 字, 全文介绍eMMC 内部系统框架, Bus 总线宽度, 总线Speed Mode, 了解即可。对应Bus 总线重点看 8 Bit 即可, Speed Mode 重点看 HS400。几乎所有的系统都是跑在…

Java并发编程-synchronized

目录 1. synchronized在jdk 1.6中的优化 1.1 锁消除 1.2 锁粗化 1.2 锁升级/锁膨胀 1.2.1 锁升级原理 1.2.2 自适应自旋锁 2. synchronized实现原理 3. synchronized和Lock的对比 1. synchronized在jdk 1.6中的优化 在JDK1.5的时候,Doug Lee推出了ReentrantLock,lock的…

【密码学复习】第九讲 密钥管理(一)

密钥管理简介 • 柯克霍夫斯原则(Kerckhoffs Principle) 即使密码系统的任何细节已为人悉知&#xff0c;只要密钥未泄漏&#xff0c;它也应是安全的(19世纪). 密钥安全&#xff1a;三分技术&#xff0c;七分管理 密钥管理就是在授权各方之间实现密钥关系的建立和维护…

dom4j 读取xml配置文件,根据配置文件利用反射创建对象

pom.xml <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0"xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation"http://maven.apache.org/POM/4.0.0 …

maven打包命令打出的可执行的jar包和可依赖的jar包的区别

目录 引出问题: 介绍打包插件 下面开始打包: 解压比较这两个jar包的区别: 引出问题: 当我建了一个maven的springboot项目A写了一个工具类,我把A项目打包成jar包去给B项目用,结果 B项目报错找不到这个jar包. 百度后发现原来jar包分为可执行jar包和可被依赖的jar包 介绍打包…

二、医院设置管理

文章目录 一、医院设置管理1、项目开发流程1.1 定义路由模块1.2 定义api模块1.3 定义页面组件脚本1.4 定义页面组件模板1.5 测试数据通信1.6 跨域处理 2、分页查询2.1 定义页面组件脚本2.2 定义页面组件模板2.3 表单查询 3、删除3.1 定义api模块3.2 定义页面组件模板3.3 定义页…

Midjourney|文心一格prompt教程[进阶篇]:Midjourney Prompt 高级参数、各版本差异、官方提供常见问题

Midjourney|文心一格prompt教程[进阶篇]&#xff1a;Midjourney Prompt 高级参数、各版本差异、官方提供常见问题 1.Midjourney Prompt 高级参数 Quality 图片质量是另一个我比较常用的属性&#xff0c;首先需要注意这个参数并不影响分辨率&#xff0c;并不改变分辨率&#x…

【C++】实现一个日期计算器

&#x1f307;个人主页&#xff1a;平凡的小苏 &#x1f4da;学习格言&#xff1a;命运给你一个低的起点&#xff0c;是想看你精彩的翻盘&#xff0c;而不是让你自甘堕落&#xff0c;脚下的路虽然难走&#xff0c;但我还能走&#xff0c;比起向阳而生&#xff0c;我更想尝试逆风…

线程池学习

一、线程池的7个核心参数说明&#xff1a; corePoolSize&#xff1a;核心线程数 maximumPoolSize&#xff1a;最大线程数 keepAliveTime&#xff1a;最大空闲时间 unit&#xff1a;最大空闲时间单位 workQueue&#xff1a;任务队列 threadFactory&#xff1a;表示生成线程…

1.Hyperledger Fabric架构介绍

&#xff08;1&#xff09;Hyperledger定义&#xff1a; Hyperledger是一个开放源代码的区块链项目合作组织&#xff0c;旨在推动跨行业的企业级区块链解决方案的发展。该项目由Linux基金会于2015年发起&#xff0c;致力于建立一个可靠、安全和可扩展的区块链框架和工具集。Hy…

堆结构 - 大根堆、小根堆

在开发语言中&#xff0c;heap在使用层次的名字叫PriorityQueue&#xff08;优先级队列&#xff09;&#xff0c;PriorityQueue数据结构的名字就叫做堆&#xff0c;底层就是用堆结构实现的。 完全二叉树 空树也算是完全二叉树每一层都是满的也算是完全二叉树如果层不满&#…

魔改车钥匙实现远程控车:(番外)在macOS上安装使用MicroPython

前言 哈哈&#xff0c;各位可能会奇怪为啥上一篇文章还在说怎么在 ESP32C3 上安装 Arduino&#xff0c;现在怎么又变成了安装 MIcroPython。 其实是因为上次写 Arduino 还是我高中时候的事了&#xff0c;已经不太会了。 虽然 MIcroPython 我从来没有接触过&#xff0c;但是 …

Microsoft Office 2003的安装

哈喽&#xff0c;大家好。今天一起学习的是office2003的安装&#xff0c;这个老版本的office可是XP操作系统的老搭档了&#xff0c;有兴趣的小伙伴也可以来一起试试手。 一、测试演示参数 演示操作系统&#xff1a;Windows XP 不建议win7及以上操作系统使用 系统类型&#xff…

Springboot 搭建WebService客户端+服务端

WebService简介 Web Service技术&#xff0c; 能使得运行在不同机器上的不同应用无须借助附加的、专门的第三方软件或硬件&#xff0c; 就可相互交换数据或集成。依据Web Service规范实施的应用之间&#xff0c; 无论它们所使用的语言、 平台或内部协议是什么&#xff0c; 都可…