OpenGL-03-Shader
CPU端设置着色器
着色器程序在OpenGL中是以C风格的字符串保存的,在使用前需要进行动态编译。
创建着色器
123unsigned int shader;shader = glCreateShader(type);// type = GL_VERTEX_SHADER 或 GL_FRAGMENT_SHADER
编译着色器代码
12glShaderSource(shader, 1, &shaderSource, NULL);glCompileShader(shader);
glShaderSource
第一个参数要编译的着色器对象。
第二参数指定了传递的源码字符串数量,这里只有一个。
第三个参数是顶点着色器真正的源码。
第四个参数指定字符串长度的数组。
glCompileShader
编译着色器代码。
像素着色器等处理相同
连接着色器代码
我们需要将不同的Shader代码连接成一个ShaderProgram才能使用。
12345unsigned int shaderProgram;shaderProgram = glCreateProgram();glAttac ...
OpenGL-02-VAO&VBO&IBO
VBO, Vertex Buffer Object 顶点缓冲对象
VBO的作用
在GPU内存中存储大量顶点的对象。避免多次从CPU传递数据到GPU从而影响性能。
使用VBO
创建VBO
创建一个缓冲对象。使用glGenBuffers函数生成一个带有缓冲ID的VBO对象
1234unsigned int VBO;//Buffer的IDglGenBuffers(1,&VBO);//函数原型:void glGenBuffers(GLsizei n,GLuint * buffers);//GLsizei n —— 声明的缓冲区数量//GLuint buffer —— 缓冲区ID的指针
绑定VBO
用于确定缓冲区的类型。可以同时绑定多个缓冲,只要它们是不同的缓冲类型。使用glBindBuffer函数把新创建的缓冲绑定到GL_ARRAY_BUFFER目标上。
从这一刻起,我们使用的任何(在GL_ARRAY_BUFFER目标上的)缓冲调用都会用来配置当前绑定的缓冲(VBO)。
1234glBindBuffer(GL_ARRAY_BUFFER, VBO);//函数原型:void glBindB ...
OpenGL_01_环境配置
初始图形API
图形API是软件与硬件沟通的桥梁,提供了一系列可以操作图形、图像的函数。现在常用的图形API有OpenGL、DirectX、Vulkan,其中DX仅支持Windows平台,而OpenGL和Vulkan都是跨平台的图形API,可以支持IOS系统、安卓系统等。随着时代的进步,OpenGL的使用正在逐渐减少,未来Vulkan是更好的发展方向。
不过严格来说,OpenGL本身并不是一个API,它仅仅是一个由Khronos组织制定并维护的规范(Specification)。具体来说,你不太可能找到一个OpenGL的函数的具体实现。因为这些函数的具体实现是由硬件厂商(如AMD、Nvidia、微星等)来做的,他们只是根据OpenGL制定的规范针对他们各家的硬件来完成具体的实现。所以OpenGL函数的具体实现方式与你的电脑GPU品牌型号有关。
初识OpenGL
核心模式和立即渲染模式
OpenGL3.2前:使用立即渲染模式(Immediate mode,固定渲染模式),绘图方便,自由度低
OpenGL3.2后:使用核心模式(Core-profile),绘图相对麻烦,自由度高
拓展
...
C#垃圾回收GC机制
C#的值类型和引用类型
值类型,int、float、string等基础数据类型称为值类型,创建的值类型存储在栈上
引用类型,是一个指向某对象的指针,如自定义数据类型,自定义的类等,使用new关键字创建,存储在堆上
C#的拆箱装箱
拆箱装箱指object类型和其他类型的互相转换。
object是C#中所有类型的基类,其中有一些静态函数、虚函数,比如用于比较对象是否相同等。
装箱
指将其他类型转换为object类型。
从内存角度讲是从堆复制到栈上。
拆箱
指讲object类型的值转换为其他类型。
从内存角度讲是从栈复制到堆的过程。
缺点
拆箱可能失败,要做检查
尽量避免频繁拆装箱,因为该过程对性能消耗比较大
C#的GC
GC,即Garbage Collection,用于回收不再引用的引用类型,避免内存泄露。
C#的GC机制
主要基于引用计数和跟踪算法实现的GC。当一个对象没有任何引用指向它时,垃圾回收器就会认为这个对象是不再需要的,从而将其占用的内存回收。
C#的垃圾回收器主要包括三个代(Generation):第0代、第1代和第2代。不同代的对象具有不同的生命周期和回收频率。第0 ...
内存对齐
补充一下结构体的知识。
结构体回顾
以前以为结构体的内存大小就是结构体中所有变量内存大小的总和。
但有次运行了下面的代码
1234567891011121314151617struct A { int a; //4 char b; //1 double c; //8};struct B{ char a;//1 int b;//4 double c;//8 char d;//1}int main() { std::cout << "sizeof(A) = " << sizeof(A) << std::endl; std::cout << "sizeof(B) = " << sizeof(B) << std::endl; return 0;}
输出结果
12sizeof(A) = 16sizeof(B) = 24
显然,如果只是将结构体中所有变量的内存大小相加,A应该是13,B应该是14啊,真是奇怪。
原因就是为了 ...
设计模式——单例模式
单例模式
单例模式保证全局仅有一个类的实例,并提供相应的访问接口。
可以用做游戏管理类等
多种单例模式
懒汉模式
饿汉模式
手撕单例模式
实现要点:
构造函数和析构函数是私有的
成员变量和返回单例的成员函数设置为静态的
禁用拷贝构造函数和赋值运算符
01
02
03
04
05
06
进程和线程
进程与线程的区别
基本概念
进程:资源分配的基本单位 一个软件就是一个进程
线程:cpu调度的基本单位 一个进程可以有多个线程在运行
相同
进程和线程在Linux中都是由task_struct结构体定义的
不同
并发性
进程切换效率低
需要上下文切换(cpu寄存器、程序计数器、用户空间信息、内核空间pcb)
线程切换效率高
需要上下文切换(cpu寄存器、程序计数器)
内存
进程有独立的虚拟地址空间。
线程没有独立的虚拟地址空间,共享进程的内存,有栈、程序计数器、本地存储等独立空间。
所属关系
线程必须依靠进程才能运行
进程包含多个线程
健壮性
进程的健壮性更好
一个进程出错不会影响到其他进程(进程间是相对独立的)
一个线程出错整个进程都会出错。
C++的内存模型
C++内存模型学习笔记
以《C++ Primer Plus》第九章为准
编译过程
C/C++、C#等都是高级语言,要在机器上运行还需要翻译成机器语言,这一过程称为编译
编译经过四大过程:
预编译 把头文件的函数声明拷贝到源文件 创建一个.i/.ii文件
编译 语法分析,符号汇总
汇编 生成函数名到函数地址的映射。便于之后函数定位 创建.obj目标文件
链接 将多个文件的符号表汇总合并 将目标文件、库代码、启动代码合并
内存模型
C++没有明确的内存模型,但通常可以按如下内容理解。
C++内存有四个部分:
代码段 存储程序的执行代码
数据段 存储全局变量、静态变量、常量
堆内存 用于存储在程序运行时使用new或malloc申请的动态内存,需要程序员手动delete或free。
栈内存 用于存储局部变量和函数调用信息。栈内存分配和释放是由编译器自动管理的,一旦函数调用结束,这部分内存将被释放。
C++11的内容(并行、锁等)
还没学到
MIT_6S081_Introduction
视频链接
About Lectures
Lecture Goals
O/S Design 操作系统设计理念
Hands-on experience 实操经验
About O/S
O/S known as Operating System.
O/S Purposes
Abstract hardware
multiplex 一个硬件为多个进程复用
isolation 进程的独立性
sharing 数据的共享
security 线程的安全性
performance
range of uses
O/S Organization
图片
kernel自启动时便会开始运行,负责内存申请、网络链接(TCP/IP协议)等,是用户层和硬件的桥梁
Why hardware programing is hard
unforgiving
tensions
efficient——abstract
powerful——simple api
排序算法
附上常用排序算法的一览表
冒泡排序
依次遍历序列每个元素,进行两两比大小,如果顺序错误则交换,遍历完所有即为有序序列。
算法步骤:
比较相邻元素大小,错误则交换
对每一组元素做上述工作,从开头到尾进行处理
持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。
123456789101112void bubble_sort(std::vector<int>& vec) { int length = vec.size(); for (int i = 0; i < length - 1;i++) { for (int j = 0; j < length - 1 - i;j++) { if (vec[j] > vec[j+1]) { int temp = vec[j]; vec[j] = vec[j + 1]; vec[j + 1] = temp; } } }}
选择排序
每次选择一个最小(最大)的元素排列到最前
算法步骤 ...


