[读书笔记] 函数式编程读书精粹
函数式编程读书精粹
[读书笔记] 第一章 函数式编程基础
第一章 函数式编程基础
函数式编程的益处
装逼
Yagur Alex - Functional Programming with C - 2024.pdf - p22 - But why should you consider adopting functional programming in your projects? The benefits aremany, including the following
C#对函数式编程的支持
Lambda表达式
LINQ
数据类型不可变
模式匹配
object obj = "Hello, World!";if (obj is string str) // 模式匹配{ Console.WriteLine(str.ToUpper()); // 输出 "HELLO, WORLD!"}
委托与事件
怎么写函数式代码
表达式写法
// 非函数式写法:命令式int sum = 0;foreach (var number in num ...
[读书笔记] glTF格式入门(三)--Buffer,BufferView,Accessor
Buffer
一个Buffer表示了一个二进制数据块.
BufferView
BufferView是对Buffer的切分.切分通过byteOffset和byteLength两个属性来定义.
同时,每个BufferView对象包括了一个target属性,用于对BufferView引用的数据进行分类.
"bufferViews" : [ { "buffer" : 0, "byteOffset" : 0, "byteLength" : 6, "target" : 34963 }, { "buffer" : 0, "byteOffset" : 8, "byteLength" : 36, "target" : 34962 }
上图浅色部分(无意义部分)用于数据对齐 ...
[读书笔记] glTF格式入门(二)--glTF基本结构
glTF基本结构
glTF文件本质上是一个Json文件,其描述了整个3D场景的内容.
glTF的元素
可以将glTF的元素分为两类: 核心元素与拓展元素
核心元素
asset: 保留了glTF文件的元数据, 如版本号, 作者, 标题等信息.
scenes: 场景列表, 用于指定场景的层级结构.
nodes: 节点列表, 用于指定场景中的对象及其关系.
materials: 材质
meshes: 网格
accessors: 访问器列表, 用于指定缓冲区视图中的数据格式.
bufferViews: 缓冲区视图列表, 用于指定缓冲区中的数据.
buffers: 缓冲区列表, 用于存储二进制数据.
Textures: 纹理
Images: 图像列表, 用于指定纹理的图像数据.
Samplers: 采样器列表, 用于指定纹理的采样方式.
Animations: 动画
Cameras: 摄像机
Skins: 蒙皮
拓展元素
拓展元素让glTF可以支持更多功能,比如压缩网格,透明材质,GPU Instancing等.
详细的拓展元素可以参考官方文档
外部数据引用
二进制数据,比如3D ...
[读书笔记] glTF格式入门(一)--概述
简介
glTF(GL Transmission Format) 是一种3D模型格式.被称为是"3D"的JPEG.
其主要优点有:
轻量化
快速加载
跨平台
包含完整3D数据,包括:
几何
材质
动画
场景结构与层级
为什么需要glTF
glTF正如其名称所言,目标是在于作为一种便于传输的中间格式.
当前的各种3D格式并不能够方便地在互联网上进行传输,以及直接高效地进行渲染.glTF正是为了解决这个问题.
glTF相较于其他格式的优势在于:
OBJ: 简单,兼容好,但功能有限
FBX:功能强大,但专有格式,文件大
glTF:轻量,功能完全,便于传输.
[读书笔记] OpenGL学习笔记-十四-帧缓冲
创建帧缓冲
unsigned int fbo;glGenFramebuffers(1, &fbo); // 第一个参数为生成的帧缓冲个数,第二个参数为帧缓冲ID的指针
绑定帧缓冲
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
此时绑定的fbo能读能写,长相十分英俊
我们也可以单独设置读取的fbo和写入的fbo
glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo);glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo);
帧缓冲需要满足的条件
通过执行上面的步骤,我们可以创建一个fbo,但是还不能使用它,因为一个完整的帧缓冲需要满足以下条件:
附加至少一个缓冲(颜色,深度,模板)
至少有一个Attachment(颜色附件)
所有附件都必须是完整的(有内存)
每个缓冲应该都有相同的样本数
我们可以使用glCheckFramebufferStatus函数来检查帧缓冲的状态,如果状态为GL_FRAMEBUFFER_COMPLETE,则说明帧缓冲满足条件,可以用了.
GLenum ...
[读书笔记] OpenGL学习笔记-十三-面剔除
我们人类是低级的三维生物,无法看到物体背后的东西,但我们却老老实实地渲染了背后的三角形然后在深度测试中丢弃掉.这难道不是一种算力浪费吗?
这就是剔除技术的用武之处了,我们可以通过剔除掉那些看不见的三角形来节省渲染时间和算力.理论上可以节省50%以上的时间.
开启面剔除
在OpenGL中,使用以下代码开启面剔除:
glEnable(GL_CULL_FACE);
我们可以设置剔除的面(可能有的外星人只能看到背面而看不到正面)
glCullFace(GL_FRONT); //剔除正面glCullFace(GL_BACK); //剔除背面glCullFace(GL_FRONT_AND_BACK); //剔除正背面
[读书笔记] OpenGL学习笔记-十二-混合
在之前的文章中提到,fragshader最终输出一个vec4的颜色值.然而,对于一个颜色我们只需要rgb三个分量就够了,最后一个分量是干嘛的呢?
最后一个通道是alpha通道,表示颜色的透明程度.对于一些图片来说,不如说草,我们不要其中的一些像素,这是透明通道就派上用场了.
上图草的背景我们是不需要的,设置透明度为0,需要的部分则为1.
但是我们并没有告诉OpenGL如何处理透明通道.所以在片段着色器中我们写下如下代码:
vec4 texColor = texture(texture1, TexCoords);if(texColor.a < 0.1) discard;FragColor = texColor;
使用discard命令丢弃透明度小于0.1的像素,这样就能达到透明效果.
但是对于一些别的半透明物品,比如玻璃,我们不能直接丢弃像素,而是需要按照某种规则进行和混合.
为了达到效果,我们首先要开启混合
glEnable(GL_BLEND);
启用混合后,我们需要告诉OpenGL如何混合颜色.
OpenGL使用这个方程混合颜色:
其中:
Cs:源颜色
Cd:目标 ...
[读书笔记] OpenGL学习笔记-十一-模板测试
先看这个效果:
发现奇怪之处了吗?
明明是3D的场景,但却没有厚度.
这使用到了模板测试
模板测试
模板测试原理如下大致如下:
开启模板测试
使用以下代码开启模板测试:
glEnable(GL_STENCIL_TEST);
注意别忘了清除模板缓冲
glClear(GL_STENCIL_BUFFER_BIT);
模板函数
和深度测试一样,模板测试也需要设置模板函数.
使用以下代码设置模板函数:
glStencilFunc(GL_ALWAYS, 1, 0xFF);
其中参数意义如下:
func: 选择模板测试函数,这里选择GL_ALWAYS,表示测试时总是通过.
ref: 参考值,这里设置为1.
mask: 掩码值,这里设置为0xFF,表示所有位都可以修改,即启用模板缓冲写入.设置为0x00则禁止写入.
在模板测试后会进行深度测试.我们可以设置不同情况下OpenGl如何更新模板缓冲.
使用以下代码设置模板缓冲更新规则:
glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
其中三个参数如下:
sfail: 发生模板测试失败,深度测试成功时,模 ...
