自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(86)
  • 收藏
  • 关注

原创 图像渲染 抗锯齿

锯齿的产生图形渲染中的锯齿是指在渲染结果图像上颜色剧烈变化的区域出现锯齿状一样的斑纹的现象。在图像色彩边缘线上,由于边缘两边的颜色差异很大,这样的现象特别明显。锯齿现象本质上是因为不同频率信号之间转换之后造成的数据失真。因此锯齿现象也被称为走样(Aliasing)。常见的走样有几何走样,着色走样、动画走样。消除锯齿现象的技术就是抗锯齿,也被称为反走样(Anti- Aliasing,AA)。抗锯齿就是通过一些手段来重构丢失的信号。我们通常用的抗锯齿算法实际上是降低锯齿,并非消除锯齿。抗锯齿算法

2021-10-09 13:40:50 833

原创 渲染管线相关

1. 准备好顶点数据和顶点连通性数据。顶点数据包括顶点的位置、颜色、纹理坐标、法线等数据,而顶点连通性数据则是描述顶点之间如何连接组合的数据,如这边两个顶点是连成一条线,这边三个顶点组成一个三角形。2. 将第一步获取的顶点数据进行处理,包括顶点位置变换,顶点光照计算,生成纹理坐标等操作,处理完后输出到下一步。(顶点着色器负责阶段)3. 根据上面提供的顶点数据和顶点连通性数据,将点连成线,线连成面。把零零散散的顶点组装成一个一个的图元,并且将图元进行栅格化,即处理成一个一个的像素格子,并且决定了每个像

2021-10-09 13:34:29 156

原创 Lua快速入门

为什么用Lualua是一门非常简单,易于上手的语言。它的简单可以从两个方面来说,一是嵌入宿主语言非常简单,另一方面,对开发者友好,语法简单,完全过程式,没有繁重的OOP负担。对于端游,脚本是锦上添花的东西。但是到了手游时代,脚本就是刚需。因为客户端发一个安装包很麻烦,在ios上每次更新都需要提交给苹果爸爸审核,审核通过以后才可以发出来给用户下载,这个时间很长且不可控。一个安装包很麻烦,在ios上每次更新都需要提交给苹果爸爸审核,审核通过以后才可以发出来给用户下载,这个时间很长且不可控。Lua

2021-10-09 13:32:40 1619

原创 游戏内存管理

游戏内存中会出现的问题内存泄露忘记回收内存,函数退栈导致丢失了指针,就再也找回不了new的内存地址,这时内存一直就会被占用着。内存碎片由于对堆内存的分配/释放的顺序是随机的,导致申请的内存块随机分布于原始内存,倘若分布不是连续的(随机顺序往往导致多个内存块都是相隔开的),那么便会产生“洞”。随着时间推移,堆内存越来越多出现这些“洞”,导致可用的自由内存块被拆分成多个小内存块。这就导致即使有足够的自由内存,分配请求仍然可能会失败。内存页切换问题虚拟内存系统把不连续的物理内存块(即

2021-10-09 12:08:57 269

原创 游戏寻路算法

A*算法从起点A开始,并把它就加入到一个由方格组成的open list(开放列表)中。这个open list有点像是一个购物单。当然现在open list里只有一项,它就是起点A,后面会慢慢加入更多的项。Open list里的格子是路径可能会是沿途经过的,也有可能不经过。基本上open list是一个待检查的方格列表。 查看与起点A相邻的方格(忽略其中墙壁所占领的方格,河流所占领的方格及其他非法地形占领的方格),把其中可走的(walkable)或可到达的...

2021-10-08 23:05:16 95

原创 碰撞检测相关

游戏中碰撞检测分为两个阶段:broad phase 和 narrow phase。接下来要介绍的就是broad phase。在broad phase这个阶段,我们的主要任务是将屏幕上的物体进行筛选,筛选出最可能发生碰撞的物体集合。我们就需要一个这样的算法去将屏幕上可能和不可能发生碰撞的物体区分开来。碰撞检测_WADE-CSDN博客_碰撞检测四叉树四叉树是一个每个父节点都具有四个子节点的树状数据结构。我们将屏幕划分为四个区域,用于区分处于不同位置的物体,四叉树的四个节点正合适表示这四个区域。方便

2021-10-08 22:54:04 311

原创 凸包算法(Graham扫描法)

凸包算法(Graham扫描法) - 程序员大本营时间复杂度:O(n㏒n)思路:Graham扫描的思想是先找到凸包上的一个点,然后从那个点开始按逆时针方向逐个找凸包上的点,实际上就是进行极角排序,然后对其查询使用。步骤:1.把所有点放在二维坐标系中,则纵坐标最小的点一定是凸包上的点,如图中的P0。2.把所有点的坐标平移一下,使 P0 作为原点,如上图。3.计算各个点相对于 P0 的幅角 α ,按从小到大的顺序对各个点排序。当 α 相同时,距离 P0 比较近的排在前面。例如...

2021-10-08 22:44:41 232

原创 面向数据编程

面向对象编程层层抽象造成臃肿,导致运行效率降低,而这是性能要求高的游戏编程领域不想看到的。面向过程:建立解决问题所需的各个步骤(函数)。面向对象:建立解决问题所需的各个模型(类)。面向数据:考虑数据的存取及布局(数据)。值得一说的是,面向过程和面向对象都是解决问题的一种方法,而面向数据只是一种优化的设计思想,而非解决问题的方法。冷数据/热数据分割我们希望CPU缓存存储的是经常使用的数据,而不是那些少用的数据。这就引入了冷数据/热数据分割的概念了。热数据:经常要操作使用的数据,我们一般可

2021-10-08 22:13:19 2381 1

原创 ECS设计框架

ECS,Entity(实体) Component(组件) System(系统),是一个gameplay层面的框架,它是建立在渲染引擎,物理引擎之上的,主要解决的问题是如何建立一个模型来处理游戏对象的更新操作,是对数据集合的操作。Entity(实体),有点类似于Unity中的Game Object,在ECS中,它仅仅是一个Component(组件)的组合,不具有任何代表意义,它的意义就在于对其上的Component(组件)进行生命周期管理。 Component(组件)是一个只包含数据的组件,将每个可能单

2021-10-08 21:52:34 1057

原创 HTTP劫持

运营商通过某些方式篡改了用户正常访问的网页,插入广告或者其他一些杂七杂八的东西。DNS劫持: 一般而言,用户上网的DNS服务器都是运营商分配的,所以,在这个节点上,运营商可以为所欲为。 例如,访问http://jiankang.qq.com/index.html,正常DNS应该返回腾讯的ip,而DNS劫持后,会返回一个运营商的中间服务器ip。访问该服务器会一致性的返回302,让用户浏览器跳转到预处理好的带广告的网页,在该网页中再通过iframe打开用户原来访问的地址。ifram...

2021-09-25 09:16:04 836

原创 HTTP断点续传

断点续传:指的是在上传/下载时,将任务(一个文件或压缩包)人为的划分为几个部分,每一个部分采用一个线程进行上传/下载,如果碰到网络故障,可以从已经上传/下载的部分开始继续上传/下载未完成的部分,而没有必要从头开始上传/下载。可以节省时间,提高速度。它通过在 Header 里两个参数实现的,客户端发请求时对应的是 Range ,服务器端响应时对应的是 Content-Range。Range用于请求头中,指定第一个字节的位置和最后一个字节的位置,一般格式:Range:(unit=first b

2021-09-25 09:03:02 3764

原创 进程隔离相关

进程隔离是操作系统内核对于资源管理和安全增强的特性,其最终的目的是对于操作系统内核能够更好的控制程序对资源的申请和使用,并且控制此程序可访问资源的范围并限定此程序异常之后能够影响的范围。进程隔离对硬件有一些基本的要求,其中最主要的硬件是MMU (Memory Management Unit 内存管理单元),MMU的作用简单用一句话概括就是将线性地址(虚拟地址)翻译为物理地址为什么需要线性地址(虚拟地址) 到 物理地址的翻译如果没有线性地址的概念只有物理地址会出现的问题:整个操作系统能够访问.

2021-09-24 21:28:07 186

原创 进程调度的方法

先来先服务一种简单的调度算法,适用于作业和进程调度。先来先服务算法按照进程/作业到达先后顺序来进行调度。当作业调度采用该算法时,每次调度都会从后备队列中取出最先到达的作业,为他分配内存,创建PCB,放入就绪队列中;当进程调度采用该算法时,每次调度都会从就绪队列中取出最先进入该队列的进程,给他分配处理机(处理机=CPU+主存储器+IO设备)。短作业优先作业或进程的长短是以作业或进程要求运行时间的长短来衡量的。优先级调度作业或进程的优先级来确定优先调度权。静态优先级 --- 优先级.

2021-09-24 21:21:27 209

原创 进程调度的方法

所谓进程调度方式,就是指当某个进程正在处理机上执行时,若有某个更为重要或紧迫的进程需要处理,即有优先权更高的进程进入就绪队列,此时应该如何分配处理及。两种进程调度方式非剥夺调度方式又称非抢占方式。非剥夺调度方式是指当一个进程正在处理机上执行时,即使有某个更为重要或紧迫的进程进入就绪队列,仍然让正在执行的进程继续执行,直到该进程完成或发生某种事件而进入阻塞态时,才把处理机分配给更为重要或紧迫的进程。在非剥夺调度方式下,一旦把CPU分配给一个进程,该进程就会保持CPU直到终止或转换到等待态优

2021-09-24 21:20:33 636

原创 PCM和WAV文件中存储的是啥

PCMPCM(Pulse Code Modulation----脉冲编码调制)。PCM录音就是将声音等模拟信号变成符号化的脉冲列,再予以记录。PCM信号是由1、0等符号构成的数字信号,而未经过任何编码和压缩处理。与模拟信号比,它不易受传送系统的杂波及失真的影响。动态范围宽,可得到音质相当好的影响效果。PCM 音频数据是未经压缩的音频采样数据裸流,它是由模拟信号经过采样、量化、编码转换成的标准的数字音频数据。PCM 音频数据的存储如果是单声道的音频文件,采样数据按时间的先后顺序

2021-09-23 13:50:34 912

原创 (leetcode518)1,2,5,10元零钱组合成n元方案数

动态规划用dp[x]表示组成x元有几种方案,目标是求dp[n]int change(int amount, vector<int>& coins) { vector<int> dp(amount + 1); dp[0] = 1; for (int& coin : coins) { for (int i = coin; i <= amount; i++) { .

2021-09-23 13:39:35 457

原创 ping用到的协议

ICMPICMP协议,是“Internet Control Message Protocol”(Internet控制消息协议)的缩写,是TCP/IP协议族的一个子协议,用于在IP主机、路由器之间传递控制消息。网络层协议ping的作用检查网络是否通畅或者网络连接速度ping一个网址通过DNS协议,将ping后接的域名转换为ip地址。(DNS使用的传输层协议是UDP)通过ARP解析服务,由ip地址解析出MAC地址,以在数据链路层传输。ping是为了测试另一台主机是否可达,发送一份

2021-09-23 13:31:50 1877

原创 桶排序相关

划分多个范围相同的区间,每个子区间自排序,最后合并。计数排序可以看成每个桶只存储相同元素,而桶排序每个桶存储一定范围的元素,通过映射函数,将待排序数组中的元素映射到各个对应的桶中,对每个桶中的元素进行排序,最后将非空桶中的元素逐个放入原序列中。桶排序需要尽量保证元素分散均匀,否则当所有数据集中在同一个桶中时,桶排序失效。复杂度时间复杂度:O(N)如果要排序的数据有n个,我们把它们分在m个桶中,这样每个桶里的数据就是k = n / m。每个桶内排序的时间复杂度就为O(k*logk)。m个桶

2021-09-23 13:16:58 66

原创 缺页中断相关

缺页中断就是要访问的页不在主存,需要操作系统将其调入主存后再进行访问。操作当一个进程发生缺页中断的时候,进程会陷入内核态,执行以下操作:检查要访问的虚拟地址是否合法 查找/分配一个物理页 填充物理页内容(读取磁盘,或者直接置0,或者啥也不干) 建立映射关系(虚拟地址到物理地址)重新执行发生缺页中断的那条指令...

2021-09-22 18:41:59 190

原创 拷贝构造函数为什么要用引用和const

不加引用的话会一直递归调用下去加上const,防止对引用类型参数值的意外修改。

2021-09-22 18:34:37 110

原创 函数模板的底层

编译器并不是把函数模板处理成能够处理任意类的函数;编译器从函数模板通过具体类型产生不同 的函数;编译器会对函数模板进行两次编译:在声明的地方对模板代码本身进行编译 在调用的地方对参数替换后的代码进行编译。函数模板要被实例化后才能成为真正的函数,在使用函数模板的源文件中包含函数模板的头文件,如果该头文件中只有声明,没有定义,那编译器无法实例化该模板,最终导致链接错误。...

2021-09-22 18:31:01 106

原创 vector,list,deque容器的迭代器

vectorvector的迭代器并没有另外定义为一个模版类,而是直接 typedef value_type* iterator。 更可以看出 vector 的迭代器就是一个普通指针listlist 的迭代器本身是一个模板类这个迭代器的模板类包括:定义一些类型别名 定义一个 node 成员变量 必要的构造函数和重载了的操作符其中真正起作用的是 node 成员变量,它是指向 list 链表结构的结点的普通指针可以看出,list 的迭代器只是封装了 list node 的指针 ,并重

2021-09-22 18:28:34 126

原创 fork函数

fork()函数通过系统调用创建一个与原来进程几乎完全相同的进程,也就是两个进程可以做完全相同的事,但如果初始参数或者传入的变量不同,两个进程也可以做不同的事。一个进程调用fork()函数后,系统先给新的进程分配资源,例如存储数据和代码的空间。然后把原来的进程的所有值都复制到新的新进程中,只有少数值与原来的进程的值不同。相当于克隆了一个自己。fork函数的特性fork调用的一个奇妙之处就是它仅仅被调用一次,却能够返回两次,它可能有三种不同的返回值:在父进程中,fork返回新创建子进程的进程I

2021-09-22 15:53:54 1152

原创 类模板和函数模板的区别

类模板没有自动类型推导;类模板在模板参数列表中可以有默认参数;#include <iostream>#include <string>using namespace std; //类模板template <class TypeName, class TypeAge = int>class Person{public: Person(TypeName name, TypeAge age) { this->m_.

2021-09-22 15:33:50 127

原创 模板的实例化与具体化

实例化:模板本身不会生成函数或类定义,它只是一个用于生成函数或类的方案,编译器使用模板为特定类型生成函数或类定义的过程叫做模板的实例化。具体化:为模板中抽象的泛型指定具体的类型。它包含隐式实例化、显示实例化、显式具体化、部分具体化。隐式实例化编译器使用通用模板提供的处方生成具体的类定义,声明一个对象,指出所需的类型。编译器生成对象之前,不会生成类的隐式实例化:ArrayTP<double, 30> * pt; //指针pt,不会生成对象pt = new ArrayTP&lt.

2021-09-22 15:32:39 441

原创 模板的全特化与偏特化

全特化就是限定死模板实现的具体类型,偏特化就是如果这个模板有多个类型,那么只限定其中的一部分。template<typename T1, typename T2>class Test{public: Test(T1 i,T2 j):a(i),b(j){cout<<"模板类"<<endl;}private: T1 a; T2 b;}; template<>class Test<int , char>{public:

2021-09-22 15:16:05 65

原创 智能指针管理数组

shared_ptr默认是使用delete来释放管理的资源,delete只会调用第一个元素的析构函数要使用shared_ptr来管理数组,就需要需要自定义删除器int main(){ auto Deleter=[](Connection *connection){ delete[] connection; }; Connection* c1 = new Connection[2]{string("s1"), string("s2")}; // 新建管

2021-09-22 14:25:38 324

原创 IO多路复用

I/O多路复用 (单个线程,通过记录跟踪每个I/O流(sock)的状态,来同时管理多个I/O流IO多路复用模型是建立在内核提供的多路分离函数select基础之上的,使用select函数可以避免同步非阻塞IO模型中轮询等待的问题。select, poll, epoll 都是I/O多路复用的具体的实现select用户首先将需要进行IO操作的socket添加到select中,然后阻塞等待select系统调用返回。当数据到达时,socket被激活,select函数返回。用户线程正式发起rea

2021-09-22 13:23:38 426

原创 广度优先搜索(BFS)

基本思想广度优先搜索(BFS)类似于二叉树的层序遍历算法基本思想是:首先访问起始顶点v,接着由v出发,依次访问v的各个未访问过的邻接顶点w1,w2,...,wi,然后依次访问w1,w2,...,wi的所有未被访问过的邻接顶点;再从这些访问过的顶点出发,访问它们所有未被访问过的邻接顶点,直到图中所有顶点都被访问过为止。若此时图中尚有顶点未被访问,则另选图中一个未曾被访问的顶点作为起始点,重复上述过程,直到图中所有顶点都被访问到为止。伪代码bool visited[MAX_VERT

2021-09-17 16:16:47 193

原创 Lambda表达式

Lambda 表达式的组成部分捕获子句(也称为 c + + 规范中的引导。 ) 参数列表可有可无. (也称为lambda 声明符) 可变规范可有可无. 异常规范可有可无. 尾随-返回类型可有可无. lambda 体。Capture字句Lambda 可以从周围范围访问或捕获变量。 Lambda 以捕获子句开头。 它指定捕获的变量以及捕获是通过值还是通过引用来捕获。 具有&前缀的变量通过引用访问,不包含它的变量通过值访问。空 capture 子句 [...

2021-09-16 14:13:58 176

原创 数据库索引失效

所谓失效。并不真的就是这个索引被删除了。而是在某些情况下,DBMS不会检索索引列表了。执行速度和没有这个索引时的速度一样。但是再执行另外的一条语句。同样的索引又正常起作用。所以索引的失效是针对某条sql语句,某个查询条件的,而不是针对索引本身的。哪类语句执行时索引不起作用呢。总结如下:索引字段进行判空查询时。也就是对索引字段判断是否为NULL时。语句为is null 或is not null。比如:select * from SoftWareDetailInfo whereCreateTime.

2021-09-16 13:37:32 148

原创 哪些运算符不能重载

"."(类成员访问运算符) " .*"(类成员指针访问运算符) "::"(域运算符) "siezof"(长度运算符) " ?:"(条件运算符)4个“不能改变”不能改变运算符操作数的个数; 不能改变运算符原有的优先级; 不能改变运算符原有的结合性; 不能改变运算符原有的语法结构。...

2021-09-16 13:37:08 1007

原创 数据库索引的类型和底层分类

B-TREE索引B-TREE索引加速了数据访问,因为存储引擎不会扫描整个表得到需要的数据。相反,它从根节点开始。根节点保存了指向子节点的指针,并且存储引擎会根据指针寻找数据。它通过查找节点页中的值找到正确的指针,节点页包含子节点的指针,并且存储引擎会根据指针寻找数据。它通过查找节点页中的值找到正确的指针,节点页包含子节点中值的上界和下界。最后,存储引擎可能无法找到需要的数据,也可能成功地找到包含数据的叶子页面。例:B-TREE索引 对于以下类型查询有用。匹配全名、匹配最左前缀、匹配列前缀、匹配范围

2021-09-16 13:36:53 94

原创 move和forward

调用它两的主要目的一般都是将左值类型强制转换为右值类型从而在初始化其它对象时可以调用右值引用构造函数,减少内存的拷贝;forward完美转发语句:意思是将一个传进函数的参数原封不动的传递出去(这里的原封不动指的是如果传进来之前为右值,那么就以右值传出去,如果传进来是左值,那么就以左值传出去)。表现形式就是函数的形参声明为右值引用,该参数需要传递出去就要用forward();因为参数传进函数内部后,不管是左值还是右值在函数内部都有名字(即都是左值)这个时候需要用forward将左值转变为右值,那么

2021-09-16 13:36:43 269

原创 常用锁相关

互斥锁互斥锁用于控制多线程对他们之间共享资源互斥访问的一个信号量。也就是说为了避免多个线程在某一时刻同时操作一个共享资源。例如线程池中的多个空闲线程和一个任务队列。任何时刻一个线程都要使用互斥锁互斥访问任务队列,以避免多个线程同时访问任务队列以发生错乱。在某一时刻,只有一个线程可以获取互斥锁,在释放互斥锁之前其他线程都不能获取该互斥锁。如果其他线程想要获取这个互斥锁,那么这个线程只能以阻塞方式进行等待条件锁条件锁就是所谓的条件变量,某一线程因为某个条件为满足时,可以使用条件变量使该程序处于

2021-09-16 13:36:30 43

原创 HTTPS

HTTPS包括了HTTP与SSL/TLS,也就是说在数据传输的时候,会进行加密操作,保证数据的安全HTTPS的优势数据隐私性:内容经过对称加密,每个连接生成一个唯一的加密密钥 数据完整性:内容传输经过完整性校验 身份认证:第三方无法伪造服务端(客户端)身份对称加密这种方式加密和解密同用一个密钥。加密和解密都会用到密钥。没有密钥就无法对密码解密,反过来说,任何人只要持有密钥就能解密了。以对称加密方式加密时必须将密钥也发给对方。可究竟怎样才能安全地转交?在互联网上转发密钥时,如果通

2021-09-16 13:36:16 162

原创 系统怎么把可执行文件装入内存

通常,程序以二进制执行文件的形式座落于磁盘上,比方说a.out或是prog.exe。为了在CPU上运行,程序必须先被带入内存,然后放入一个进程的上下文中。接下来我们会描述这一过程中的步骤,从编译程序到放入内存中。如下图所示:源文件被编译成目标文件,这些目标文件旨在装入任何物理内存中,这种格式称为可重定位目标文件relocatable object file。接下来,链接器linker将这些可重定位的目标文件组合为单个二进制可执行executable文件。在链接阶段,也可能包括其他目标文件或库,例

2021-09-16 13:36:09 838

原创 虚拟内存到物理内存怎么映射

程序在编译时不可能知道装载后的物理内存地址,实际上,程序编译生成的地址都是虚拟地址。在我们日常使用的 Linux 或者 Windows 操作系统下,程序并不能直接访问物理内存。为了解决这个问题,当程序装载后,会通过虚拟地址映射到真实的物理地址。内存被分成固定大小的页(Page),然后再通过虚拟内存地址(Virtual Address)到物理内存地址(Physical Address)的地址转换(Address Translation),才能访问实际存放数据的物理内存位置。页表(Page Tabl..

2021-09-16 13:36:01 1813 2

原创 main函数开始前有哪些操作

设置栈指针为栈分配相关的位置,用来放一些局部变量和其他数据初始化static静态和global全局变量,即data段的内容把全局和静态变量初始化,放在相应的位置将未初始化部分的全局变量赋初值:数值型short,int,long等为0,bool为FALSE,指针为NULL,等等,即.bss段的内容将未设置初值的全局变量赋初值全局对象初始化,在main之前调用构造函数在main之前调用构造函数将main函数的参数,argc,argv等传递给main函数,然后才真正运行ma

2021-09-16 13:35:09 229

原创 二叉平衡树

特点非叶子节点最多拥有两个子节点; 非叶子节值大于左边子节点、小于右边子节点; 树的左右两边的层级数相差不会大于1; 没有值相等重复的节点。插入节点操作平均时间复杂度 O(log(n)) ...

2021-09-15 18:32:30 75

空空如也

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除