OpenGL学习笔记2:着色器和C++
C++笔记
关键点:
- C++单个文件的编译及运行:
- 安装编译器:GNU的gcc编译器
- 编译:g++ hello.cpp,生成a.out可执行文件
- 运行:./a.out
- 数据类型:大部分与Java类似,差异点如下:
- 布尔类型:bool
- 字符:
- char, 1字节,-128~127
- unsigned,1字节,0~256
- 整型:
- short int,2字节
- int,4字节
- long int,8字节
- 浮点型:
- float,4字节
- double,8字节
- long double,16字节
- 计算类型真正所占大小:sizeof(int|float|double)
- 类型声明:typedef type newname
- 枚举:enum enum-name {} var-list;
- 声明:函数需声明才能调用
- 变量声明:extern int c;
- 函数声明:int func();
- 定义常量的方法:
- 使用 #define 预处理器
- 使用 const 关键字
- 位运算符:
- 与:&
- 或:|
- 异或: ^
- 非:~
- 左移右移:<< >>
- 函数:支持默认值及重载
- c风格的字符串:通过char[]数组实现,以’\0’结尾
- C++风格的字符串:string
- 指针:
- 指针变量:type *name;
- &:表示取地址符
- *:取值符,表示取指针变量的指针值所指向的变量值
- 创建对象:
- Person p(1, 2); // 声明时,对象已经创建
- Person* p; p = new Person(); // 动态内存,与java类似
- 引用:
- 引用变量是变量的别名,必须定义时,赋值,且无法再修改
- 语法:int i = 17; int& r = i;
- 数据结构:struct,访问成员的方法:
- 变量:book.title
- 指针:book->title
- 面向对象:class(类)
- 语法:
- 权限:public:
- 命名空间:namespace — 相当于包名,与文件名和路径无关
- 定义:namespace name {// 代码}
- 使用:
- using namespace name;
- name::fun;
- 继承:class Rectangle: public Shape(public的作用:统一修改基类里的公有和保护成员在子类里的权限,一般都为public)
- 支持运算符重载,java不支持
- 抽象方法:virtual修饰的方法
- 没有接口关键字,接口通过抽象类实现
- 多继承
- 语法:
- 异常处理:捕获所有的异常,方式:catch(…),或者使用std::exception
- 动态内存:
- 栈:局变量都在栈里分配
- 堆:动态内存,通过new 或 malloc() 分配
- 与java的差异:Object obj;的内存分配:
- 出现在函数内部,在栈上创建对象
- 类的成员变量,取决于类的对象如何创建:
- Class *pClass = new Class; // 堆
- Class class; // 栈
- 栈和堆的区别:
- 生命周期:函数执行后,要保留生命周期,只能选择堆,但堆内存不会自动回收
- 性能:在堆里创建,会出现磁盘碎片
- 大小:栈的大小有限制,堆可以很大
- 模板:相当于java的泛型
- 分为函数模板与类模板
- 模板的关键字:template
- 预处理:在编译器时期,完成的指令
- 创建宏:#define
- 条件编译:#ifndef xxx,只对部分代码编译
- 信号处理:
- 进程之间,可以通过信号来传递指令,比如结束当前进程
- 监听信号:signal(),在main()函数里,监听并添加监听处理类
- 发送信号:raise(),接收方是本进程的监听,通过ctrl+C可以对本进程发送中断程序的信号
- 多线程:C++本身不支持多线程能力,依赖操作系统支持
- 常用库及功能:
- cmath库:
- x的y次方:pow(double, double)
- 平方根:sqrt(double)
- 绝对值:abs(int)
- 向下取余:floor(double)
- 随机数:伪随机
- 设置种子:srand()
- 生成随机数:rand()
- c风格字符串的操作:
- 复制:std::strcpy(s1, s2)
- 连接:std::strcat(s1, s2)
- 长度:std::strlen(s1)
- 比较:std::strcmp(s1, s2)
- 字符串查找:std::strstr(s1, s2),返回一个指针,指向字符串 s1 中字符串 s2 的第一次出现的位置
- iostream库:
- 标准输出:std::cout << “” << std::endl;
- 标准输入:std::cin >> name
- 标准错误:std::cerr << “” << std::endl;
- 文件操作,fstream库:
- ofstream:输出文件流
- ifstream:输入文件流
- fstream:同时具有ofstream, ifstream的功能
- 文件操作流程:
- 打开文件:
- 只写打开:ofstream outfile;outfile.open(“afile.dat”);
- 只读打开:ifstream infile; infile.open(“afile.dat”);
- 读文件:infile >> data
- 写文件:outfile << data << endl;
- 打开文件:
- cmath库:
着色器
关键点:
- 着色器是使用一种叫GLSL的类C语言写成的
- 着色器的结构:
- 版本声明:#version version_number
- 变量:in type xxx; out type xxx; uniform type xxx;
- main函数
- 顶点差色器的输入为顶点属性(Vertex Attribute):
- 一般情况的上线为16个包含4分量的顶点属性
- 与硬件有关,通过GL_MAX_VERTEX_ATTRIBS查询:glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &nrAttributes);
- 着色器语言除C的基本数据类型外,还包含向量(Vector)和矩阵(Matrix)
- Vector相关的api:
- 访问4个属性:vec.x, vec.y, vec.z, vec.w
- 重组:vec2, vec3, vec4
- Vector相关的api:
- GLSL输入与输出:
- 两个着色器之间,输入和输出的类型和名称一样,就会自动匹配 —- 与顺序无关
- 顶点着色器的输入:通过layout来指定输入变量
- 片段着色器的输出:vec4颜色输出变量,指定片段最终的颜色
- GLSL的uniform:
- 作用:CPU直接向GPU的着色器发送数据的方式
- uniform是全局唯一
- 着色器里的定义:uniform type xxx;
- opengl代码设置uniform的值:
- 获取地址:glGetUniformLocation(shaderProgram, “uniform名称”)
- 使用着色器程序后,设置值:
- glUseProgram(shaderProgram);
- glUniform4f(location, 0.0f, greenValue, 0.0f, 1.0f);
- 改变三角形颜色的方法:
- 通过uniform传值给片段着色器
- 顶点数据里,添加颜色数据,再通过顶点着色器传给片段着色器
- 注意:片段着色器每次处理一个顶点,而不是一个图形