- 博客(124)
- 问答 (1)
- 收藏
- 关注
原创 C++第七章:类
程序员们常把运行其程序的人称作用户(user)。类似的,类的设计者也是为其用户设计并实现类的一个人。显然类的用户是程序员,而非应用程序的最终使用者。当我们设计类的接口时,应该考虑如何才能使得类易于使用。而当我们使用类时,不应该顾及类的实现机理。作为一个设计良好的类,既要有直观且易于使用的接口,也必须具备高效的实现过程。书籍类源代码:// 返回数据的唯一编号 std :: string isbn() const {
2023-05-28 11:49:26
77
原创 C++第六章:函数
一个典型的函数包括以下部分:返回类型(return type)、函数名字、由0个或多个形参(parameter)组成的列表、函数体。我们通过调用运算符来执行函数,调用运算符的形式是一对圆括号,它作用于一个表达式,该表达式是函数或者指向函数的指针。圆括号之内是一个用逗号隔开的实参列表,我们用实参初始化函数的形参。调用表达式的类型就是函数的返回类型。使用函数的示例:// 函数fact计算n的阶乘 int fact(int n) {
2023-05-26 13:48:03
411
原创 C++第三章:字符串、向量和数组
如何初始化类的对象是由类本身决定的。一个类可以定义很多种初始化对象的方式,只不过这些方式之间必须有所区别:或者是初始值的数量不同,或者是初始值的类型不同。初始化string对象最常用的方法如下:初始化格式初始化结果string s1;空字符串st的值(st为字符串)st的值(st为字符串)valuevaluen个c注意字符串字面值"value"严格来说其字符串最后还有一个’\0’表示字符串的结束,当将字符串字面值赋值给string对象时它会抛弃’\0’。
2023-05-25 16:15:49
266
原创 C++第二章:变量和基本内置类型
实例代码:");return 0;基本形式:首先是类型说明符,随后紧跟一个或多个变量名组成的列表,其中变量名以逗号分隔,最后以分号结束。列表中每个变量名的类型都由说明符指定,定义时还可以位一个或多个变量赋初值。string是一种可变长字符序列的数据类型,在C++库中提供了几种初始化string类对象的方法,其中一种就是上文中把字面值拷贝给string对象。通常情况下,对象是指一块能存储数据并具有某种类型的内存空间。
2023-05-23 21:08:04
553
原创 C++第一章:开始
我们通过定义一个类(class)来定义自己的数据结构,一个类定义了一个类型,以及与其相关联的一组操作。类类型(class type)。为了使用类必须了解三件事情:(1)类的名称是声明(2)类是在哪里定义的(3)类支持什么操作一般而言,类的作者决定了类类型对象上可以使用的所有操作。当我们调试程序时,可能需要反复从键盘输入,这是非常枯燥的。大多数操作系统支持文件重定向,这种机制允许我们将标准输入和标准输出与命名文件关联起来。
2023-05-22 13:15:53
359
原创 GAMSE101-作业1
运行程序如果出现缺少.dll,就把对应的文件放到你VS STDIO的运行目录下(别放错了,不知道放哪就在每个Debug放一个)。
2023-05-20 19:07:27
17
原创 计算机图形学-GAMES101-13
光沿着直线传播。光线和光线不会发生碰撞。光线追踪运用光路的可逆性。光线从光源发出,会发生反射、折射,光线追踪就是模拟这个过程。追踪:从终点(眼睛或相机)开始,连接到视口上的每一个像素。连接会产生一条光路,我们沿着每条光路追踪场景中的物体。如果追踪到某个物体,我们再将物体和光源进行连线,判断物体是否能被光源照亮。如果物体能被光源照亮,那么我们就可以计算这条光路上的能量,随着进行着色。
2023-05-20 16:51:26
556
原创 计算机图形学-GAMES101-12阴影
硬阴影就是被本影挡住的部分,而软阴影是被部分光源照亮。如果要做出软阴影,必须使用具有一定体积大小的点光源。Shadow Mapping使用多大的分辨率?Shadow Mapping需要更多的计算。硬阴影和软阴影有什么区别?只能计算硬阴影(理论上)
2023-05-20 13:34:16
577
原创 计算机图形学-GAMES101-11
如上图所示,我们使用黑色的起点-终点和两个蓝色的弯曲控制点来表示一条曲线。要注意的是,我们想要连接起来的曲线连续。因为我们知道Bezaer曲线在起点和终点处的切线方向分别都等于它们和对应控制点的连线,因此我们需要使得前一条曲线的终点和对应控制点的连线经过后一条曲线起点的控制点,当然这里说的两条曲线分别的终点和起点其实是一个点,我们要求这三点共线,并且中间拿个点应该是两个控制点的终点,这样才能保证切线的大小相同。使用三维空间中的点,即可插值出三维空间中的曲线。以上保证了曲线的C1连续,工业上使用C2连续。
2023-05-20 12:59:58
1019
原创 计算机图形学-GAMES101-10
原模型网格->逐面Shading->逐像素Phong Shading->纹理贴图->换个纹理再贴图->环境光照。
2023-05-20 11:18:53
703
原创 计算机图形学-GAMES101-9
Nearset是一种纹理的过滤方式,它表示当屏幕上的像素点插值出来的纹理坐标为(x,y)时,找到纹理贴图中与(x,y)距离最近的像素点,把贴图中像素点的属性赋值给屏幕像素点。问题分析:当在远处时,一个像素点内部包含了一大块纹理区域,这一大块纹理区内颜色的变化是很快的,而我们只使用一个采样点区采样它,因此我们得到的颜色值是不足以代表这一整块区域的,也因此我们的采样频率远低于信号的频率,就会发生走样。我们根据像素的纹理坐标,找到它四周的纹理像素点,根据纹理坐标到纹理像素点之间水平和竖直的相对距离进行插值。
2023-05-19 20:28:55
1045
原创 CG-3D渲染器-0.1
需要注意的一件事是,如果我们要把x轴缩放0.5倍,我们通常会传入的scale_size为(1,0,0),也就是说我们默认认为传入0的缩放倍率表示不进行缩放,因此我们需要判断scale_size的分量如果为0则设置为1(缩放倍率为1即不缩放)。当旋转轴axis的起点pos不为原点时,我们先对原模型矩阵进行平移,将pos移到原点(0,0,0)上,使得旋转轴axis过原点。镜像矩阵我们可以认为不进行缩放,即倍率只能为1或-1,因此我们将参数axle设为整数int类型,这样判断其值是否为0而不进行操作,也很简单。
2023-05-19 16:42:21
451
原创 计算机图形学-GAMES101-8
渲染管线的流程如下图所示。场景种的模型是如何定义的?模型先定义了一系列顶点,然后定义了每个三角形分别对应的顶点,这一只需要把点按照三角形连接起来就变成了模型。首先我们将所有顶点输入到三维空间中,然后进行视图变换、投影变换、视口变换,将三维空间中的顶点映射到了二维屏幕空间中。然后我们再根据三角形的顶点信息,分别连接每一个三角形的顶点。当屏幕上存在许许多多的二维三角形时,我们遍历每一个三角形,按照三角形的包围盒去对像素进行光栅化,即对每个像素进行采样、进行深度测试,找到实际能显示在屏幕上的像素。
2023-05-17 19:43:29
306
原创 计算机图形学-GAMES101-7
场景中有很多的三角形,如果实现可见性和遮挡呢?一个简单的想法是,从远到近画,近处的物体自然会覆盖掉远处的物体,这种画法也叫画家算法。
2023-05-17 16:32:19
778
原创 计算机图形学-GAMES101-6
走样的定义:对两种频率不同的信号进行采样,根据得到的结果我们无法区分它们。下图中我们可以看到两条曲线,它们分别对应两条原始信号,如果我们使用图中圆圈的点去采样这两条原始信号,会得到相同的采样结果,这就是走样。经过上面的阐述,我们先对原始信号进行低通滤波,这样我们再进行采样,就不容易发生走样。即先进行模糊,再进行采样,这就是反走样。在实际操作中,我们应该如何模糊一个三角形?我们用一定大小的滤波器对图像进行卷积,达到模糊操作。
2023-05-17 14:24:43
235
原创 计算机图形学-GAMES101-5
长宽比Aspect ratio:width / height垂直的可视角度:fovY远近平面的距离:n和f通过长宽比和垂直的可视角度可以求出水平的可视角度。如下图所示,根据fovY和n可以计算出近平面的顶点坐标,再根据宽高比Aspect即可计算出近平面的高度,因此根据上述参数可以计算出所有屏幕的所有信息。远平面同理。因此我们只需要定义fov和宽高比Aspect以及n和f即可定义一个确定的视锥。
2023-05-17 11:23:15
133
原创 计算机图形学-GAMES101-4
当我们旋转Q角度和旋转-Q角度时,变换矩阵中旋转的部分如下图所示:旋转Q和旋转-Q的变换矩阵应该互为逆矩阵,而我们可以看到它们互为对方矩阵的转置。其实Rq是一个正交矩阵,因此其逆矩阵就是它自己的转置。当我们旋转图形一个角度为Q时,如果我们想旋转为-Q,可以直接将其变换矩阵中旋转的部分做转置。
2023-05-17 00:06:36
192
原创 计算机图形学-GAMES101-3
我们要做变换,就要找到变换前坐标和变换后坐标之间的一种关系,根据这种关系将原坐标变换为新坐标,并将坐标和变换写成矩阵形式。点和向量齐次坐标的表示,向量w=0代表了向量的平移不变性。也表述了向量+向量=向量、点-点=向量 等运算规则。扩展齐次坐标下点w分量的含义。
2023-05-16 19:21:16
505
原创 计算机图形学-GAMES101-2
表示一个方向。计算向量的方法:AB =(B-A)。向量对应的单位向量 = AB / ||AB||。向量具有平移性,我们不关心它的开始位置。向量求和:三角形法则和平行四边形法则。在代数上计算直接把向量的对应坐标相加即可。向量可表示为一个列向量。
2023-05-16 17:04:11
412
原创 OpenGL实战-调试
官方的标准使用OpenGL的GLSL参考编译器(Reference Compiler)来检查。你可以从这里下载所谓的GLSL语言校验器(GLSL Lang Validator)的可执行版本。注意如果没有检测到错误的话则没有输出。它不会显示AMD,NVidia,以及Intel的GLSL编译器之间的细微差别,也不能保证你的着色器完全没有Bug,但它至少能够帮你对着直接的GLSL规范进行检查。切换到D盘 d:转到某地址目录下 cd /d 地址。
2023-05-16 11:22:26
259
原创 OpenGL高级光照-Gamma校正
设一个颜色的值为q(x∈[0,1]),设显示器展示出来的亮度值为w,设人眼看到的亮度值为e。当显示器设备的gamma为2.2时,则w=q ^ 2.2人眼相当于二次幂,即人眼看到的颜色亮度为e=q ^ 2。因此CRT这个缺陷正好能满足人的需要,即CRT上展示的颜色亮度,就为人眼中应该看到的颜色。但有一个问题是:当我们对颜色值做变换的时候,在我们人眼中的颜色会发生意想不到的改变:比如,光的颜色向量L=(0.5,0.0,0.0)代表的是暗红色。
2023-05-14 21:42:43
11
原创 OpenGL高级-抗锯齿
当我们现在调用glfwCreateWindow,用于渲染的窗口就被创建了,这次每个屏幕坐标使用一个包含4个子样本的颜色缓冲。这意味着所有缓冲的大小都增长4倍。 现在我们请求GLFW提供了多样本缓冲,我们还要调用glEnable来开启多采样,参数是 GL_MULTISAMPLE。大多数OpenGL驱动,多采样默认是开启的,所以这个调用有点多余,但通常记得开启它是个好主意。这样所有OpenGL实现的多采样都开启了。离屏MSAA 因为GLFW负责创建多采样缓冲,开启MSAA非常简单。如果我们打算使用我们自
2023-05-14 18:40:07
6
原创 OpenGL高级-实例化
假如你有一个有许多模型的场景,而这些模型的顶点数据都一样,只是进行了不同的世界空间的变换。想象一下,有一个场景中充满了草叶:每根草都是几个三角形组成的。你可能需要绘制很多的草叶,最终一次渲染循环中就肯能有成千上万个草需要绘制了。因为每个草叶只是由几个三角形组成,绘制一个几乎是即刻完成,但是数量巨大以后,执行起来就很慢了。像这样绘制出你模型的其他实例,多次绘制之后,很快将达到一个瓶颈,这是因为你glDrawArrays或glDrawElements这样的函数(Draw call)过多。
2023-05-14 17:10:35
464
原创 OpenGL高级-几何着色器
在顶点和片段着色器之间有一个可选的着色器,叫做几何着色器(Geometry Shader)。几何着色器以一个或多个表示为一个单独基本图形(primitive)的顶点作为输入,比如可以是一个点或者三角形。几何着色器在将这些顶点发送到下一个着色阶段之前,可以将这些顶点转变为它认为合适的内容。几何着色器有意思的地方在于它可以把(一个或多个)顶点转变为完全不同的基本图形(primitive),从而生成比原来多得多的顶点。330使用这3个输出修饰符我们可以从输入的基本图形创建任何我们想要的形状。
2023-05-13 17:14:38
661
原创 OpenGL高级-GLSL
我们会讨论一些内建变量(Built-in Variable)、组织着色器输入和输出的新方式以及一个叫做uniform缓冲对象(Uniform Buffer Object)的非常有用的工具。
2023-05-13 14:05:56
594
原创 OpenGL高级-数据
1.调用glBufferSubData将数据更新到指定区域的缓冲内存空间中。2.调用glMapBuffer获取绑定到对应缓冲类型上的缓冲对象指针,再使用memcpy将数据传入其中,要记得解除映射glUnmapBuffer。
2023-05-12 18:55:28
10
原创 OpenGL高级-立方体贴图
渲染物体的顶点着色器: 渲染物体的片段着色器: 渲染天空盒的顶点着色器: 渲染天空盒的片段着色器:主程序优化 如果先渲染天空盒再渲染物体,由于场景中天空盒很多的片段可能被物体遮挡,但先渲染天空盒会对天空盒的所有片段执行片段着色器,这样会造成性能的浪费。如果我们先渲染物体,然后只渲染天空盒没有被遮挡的部分,那么会得到优化,如何渲染天空盒没有被遮挡的部分呢? 透视除法在顶点着色器之后执行,即把gl_Position的xyz除以w元素。我们需要使得天空盒在执行透视除法后z元素为1,因此我们在天空
2023-05-12 15:49:52
703
原创 OpenGL高级-帧缓冲
颜色缓冲记录帧的颜色值,深度缓冲记录深度信息,模板缓冲允许我们基于一些条件丢弃指定片段。这几种缓冲结合起来叫做帧缓冲(FrameBuffer),它被储存于内存中。 OpenGL给了我们自己定义帧缓冲的自由,我们可以选择性的定义自己的颜色缓冲、深度和模板缓冲。 定义自己的帧缓冲好处就是:我们现在可以自由的获取已经渲染场景中的任何像素,然后把它当作一个纹理图像了。我们可以在片段着色器中创建一些有意思的效果。所有这些有意思的效果统称为后处理特效。 我们目前所做的渲染操作都是是在默认的帧缓冲之上进行的。当你
2023-05-11 19:52:28
397
原创 OpenGL高级-面剔除
默认情况下,逆时针的顶点连接顺序被定义为三角形的正面。面剔除是OpenGL提高效率的一个强大工具,它使应用节省运算。你必须跟踪下来哪个物体可以使用面剔除,哪些不能。面剔除针对像立方体这样的封闭形状有效,当对封闭形状使用剔除时,如果剔除内部的面,则在外面看是同样的效果,在里面看则会看不到任何物体。
2023-05-10 13:41:03
11
原创 OpenGL高级之 混合下
使用混合时要注意物体的渲染顺序,先绘制不透明的物体,再又远及近的绘制透明物体。对于草这种全透明物体,我们可以简单的丢弃透明像素而不是混合,
2023-05-10 12:06:08
13
原创 OpenGL高级之 混合上
1.从const char转换到GLchar会报错,因此将GLchar类型转换为const GLchar。2.当SOIL_load_image加载图片错误时,glTexImage2D以加载图片的数组为参数时会报出错误代码:1281。加载图片很容易出错,无论是文件地址写错一个字母,还是诸如在浏览器里下载的莫名格式图片,都很容易加载错误。这时就会报错1281,可以看看图片是否加载成功。
2023-05-09 18:39:30
31
原创 OpenGL加载模型 之网格
所以我们要做的第一件事,就是加载一个模型文件为scene对象,然后获取每个节点对应的Mesh对象(我们需要递归搜索每个节点的子节点来获取所有的节点),并处理每个Mesh对象对应的顶点数据、索引以及它的材质属性。最终我们得到一个只包含我们需要的数据的Mesh集合。
2023-05-06 21:55:18
587
原创 OpenGL光源之 多光源
不多讲解,直接上代码,代码上都有注释,草履虫都能看懂。本文的程序来自于,这一节内容我调试了好久,一下午才把Bug修复。总结,当你拿到别人的OpenGL代码时,首先你要看主程序中的外部依赖库和一些头文件你是否具有,然后你需要对着色器的文件地址进行修改,然后就是对资源如图片的文件地址进行修改。教程原文中的代码是具有Bug的,第一个Bug就是纹理过滤方式的设置,纹理过滤方式不能将放大纹理设置为多级渐进纹理GL_NEAREST_MIPMAP_NEAREST,不然你使用glGetError会报错的。
2023-05-05 19:20:15
30
原创 OpenGL光照教程之 透光物
我们目前使用的所有光照都来自于一个单独的光源,这是空间中的一个点。它的效果不错,但是在真实世界,我们有多种类型的光,它们每个表现都不同。一个光源把光投射到物体上,叫做投光。这个教程里我们讨论几种不同的投光类型。学习模拟不同的光源是你未来丰富你的场景的另一个工具。我们首先讨论定向光(directional light),接着是作为之前学到知识的扩展的点光(point light),最后我们讨论聚光(Spotlight)。下面的教程我们会把这几种不同的光类型整合到一个场景中。
2023-05-05 14:56:03
580
原创 OpenGL光照教程之 光照贴图
前面的教程,我们讨论了让不同的物体拥有各自不同的材质并对光照做出不同的反应的方法。在一个光照场景中,让每个物体拥有和其他物体不同的外观很棒,但是这仍然不能对一个物体的图像输出提供足够多的灵活性。前面的教程中我们将一个物体自身作为一个整体为其定义了一个材质,但是现实世界的物体通常不会只有这么一种材质,而是由多种材质组成。想象一辆车:它的外表质地光亮,车窗会部分反射环境,它的轮胎没有specular高光,轮彀却非常闪亮(在洗过之后)。汽车同样有diffuse和ambient颜色,它们在整个车上都不相同;
2023-05-05 12:33:12
433
Unity 标准资源包 Unity Standard Assets
2023-03-20
unity聊天室,基于Socket网络编程
2023-03-19
C++模板类重载<<运算符
2023-05-21
OpenGL使用glViewport函数时 出现异常
2023-04-14
C# winform程序 使用控制台输出无结果?
2023-03-18
fseek应该定义到文件末尾的#之前,为什么却是在#之后?
2021-01-05
TA创建的收藏夹 TA关注的收藏夹
TA关注的人