opengl 第四课(矩阵变换)

不学细节,只看概念

见字如面:
glutMainLoop
glutSetWindowTitle
glClear
glEnable
glDisable
glPointSize
glLineWidth
gltMakeTorus

GLTriangleBatch
甜甜圈的批次类

颜色
GLfloat vGreen[] = { 0.0f, 1.0f, 0.0f, 1.0f };

M3DMatrix44f
typedef float M3DMatrix44f[16]

GLShaderManager

1
2
// 使用固定管线(固定管线类型,矩阵,颜色)
GLint UseStockShader(GLT_STOCK_SHADER nShaderID, ...);

GLMatrixStack
矩阵堆栈,数据结构[单元矩阵/矩阵/矩阵相乘/压栈/出栈/缩放/平移/旋转]

1
2
3
4
5
6
7
8
9
10
11
12
// 复制一个矩阵到栈中
inline void LoadMatrix(const M3DMatrix44f mMatrix)

// 栈顶矩阵 与 mMatrix 相乘的结果,并入栈
inline void MultMatrix(const M3DMatrix44f mMatrix)

// 顶部载入单元矩阵
inline void LoadIdentity(void)

// 压入一个矩阵
void PushMatrix(GLFrame& frame)
inline void PopMatrix(void)

GLBatch
传输顶点/光照/纹理/颜色数据到存储着色器中

1
2
3
4
5
6
7
8
9
10
11
// 开始一个批次(点的连接方式9种,顶点数)
void Begin(GLenum primitive, GLuint nVerts, GLuint nTextureUnits = 0)

// 复制 顶点数据
inline void CopyVertexData3f(GLfloat *vVerts)

// 配置完毕
void End(void)

// 提交批次
virtual void Draw(void)

GLGeometryTransform
几何变换管道

1
2
3
4
5
// 初始化管道,关联 模型矩阵栈、投影矩阵栈
inline void SetMatrixStacks(GLMatrixStack& mModelView, GLMatrixStack& mProjection)

// 获取 MVP 矩阵
const M3DMatrix44f& GetModelViewProjectionMatrix(void)

GLFrame
矩阵变换工具类

1
2
3
4
5
6
7
8
9
10
11
// 设置摄像机位置,延 Z轴 移动
inline void MoveForward(float fDelta)

// 调整观察者位置
void RotateWorld(float fAngle, float x, float y, float z)

// 获取 顶部矩阵
void GetMatrix(M3DMatrix44f matrix, bool bRotationOnly = false)

// 获取 m 摄像机矩阵
void GetCameraMatrix(M3DMatrix44f m, bool bRotationOnly = false)

GLFrustum
投影[空间|盒子]模型【正投影、透视投影】[3D->2D]

1
2
3
4
5
6
7
8
/*
1. 透视投影 (角度,宽高比W/H, 近点,远点),
2. 默认生成透视投影矩阵
*/
void SetPerspective(float fFov, float fAspect, float fNear, float fFar)

// 返回上面生成的 透视投影矩阵
const M3DMatrix44f& GetProjectionMatrix(void) { return projMatrix; }

第二部分:实战画图

待续…

opengl 课程三离屏

CoreAnimation:属于 QuartzCore 框架
QuartzCore:包含 CoreAnimation 实现的各种类
Quartz2D: C语言写的,绘图函数库,是 Core Graphics 的 API
Core Graphics:CPU渲染,
CoreImage: 专门处理图片的

复习 Core Animation 渲染

CPU
-> UIView 触发
-> UILayout 保存需要绘制渲染的内容
-> Application: 提交图层树、动画(Commit Transaction)
-> Render Server: 解析树的状态、生成绘制指令 (Decode, Draw Calls)
GPU
-> 读取帧缓存区
-> 渲染流程5部曲(顶点数据\顶点着色器\图元装配\光栅化\片源着色器)
-> 显示在屏幕(视频控制器->读取缓存信息->数模转换->显示器)


离屏渲染

查看离屏渲染:XCode -> Debug -> Color Off-screen Rendered

离屏渲染大小:屏幕像素的2.5倍

离屏渲染:GPU 需要额外渲染,需要开启离屏缓存区
如有这三个图层:layerA < layerB < layerC
A、无离屏渲染场景
GPU按照渲染流程,依次渲染各个layer
第一步:layerA -> [FrameBuffer -> 显示器 -> 清空FrameBuffer]
第二步:layerB -> [FrameBuffer -> 显示器 -> 清空FrameBuffer]
第三步:layerC -> [FrameBuffer -> 显示器 -> 清空FrameBuffer]

B、有离屏渲染场景
假如 layerC 是 layerA 的遮罩,
所以 layerA 就不能执行上面的第一步,需要等待 layerC 的加入才可以计算出最图形
步骤应该如下
layerA -> OffScreenBuffer
-> layerB -> OffScreenBuffer -> 合并计算
-> layerC -> OffScreenBuffer -> 合并计算
-> FrameBuffer -> 显示器 -> 清空FrameBuffer

效率:复用
CGLayer 光栅化 shouldRasterize 建议

  • 不被重复使用
  • 不是静态图片
  • 复用率大于 0.1 秒
  • 屏幕像素的2.5倍

油画算法:由远到近
固定管线:GLShaderManager::UserStockShader


GLSL 初见 – 参数的传递

Vsh 顶点着色器

  1. Attributes(属性通道)

顶点数据、投影矩阵、模型矩阵
纹理坐标(映射关系)
2. Uniform(统一批次,只设置一次的)
变换矩阵、
3. Texture(一般不这么传递)

Fsh 片源着色器

  1. 来自vsh顶点着色器
  2. Uniform
  3. Texture 纹理数据

投影

正投影
透视投影

有点意思1
有点意思2

opengl 单词理解二

hello 图形 复习下

图片渲染流程

  • 顶点数据
  • 顶点着色器
  • 图元装配
  • 光栅化
  • 片源着色器

图元装配:顶点的连接方式(9种)
固定管线:OpenGL系统封装好了的,顶点着色器、片源着色器
帧缓存区:显存区域
位图大小:像素W * 像素Y * 4(rgba)

图片撕裂:上一帧的位图数据 + 下一帧的位图数据(CPU解码、GPU渲染,达不到显示器刷新率)
防止撕裂:垂直同步 + 双缓存区
垂直同步:缓存区加锁,就会出现掉帧
双缓存区:两片缓存区分别存 上一帧、下一帧
掉帧:GPU 多次的垂直同步,造成渲染同一帧
三缓存区:减小掉帧(合理使用CPU、GPU时间)

Core Animate

  • 上连视图框架(UIKit\APPKit),下接图形API(OpenGL/Metal)
  • 复合引擎,渲染、构建、动画

UIView:交互的,布局、事件、子View管理、layer载体
CALayer: 显示的,渲染、动画、位图载体(content: CGImage?)


UIView 如何显示到屏幕上面的

CPU
-> UIKit (UIView,事件、交互、控制)
-> Core Animation (CALayer,要绘制的内容–纹理)
—> Commit Transaction (构建、计算、解码)
—> Render Server (下一个RunLoop,提交到帧缓存区)
GPU
-> 读取帧缓存区
->(CPU、GPU吞吐量与显示器刷新率差异大,出现撕裂)
->(垂直同步:解决撕裂,出现掉帧)
->(三缓存区:缓解掉帧)
-> 渲染流程5部曲(顶点数据\顶点着色器\图元装配\光栅化\片源着色器)
-> 显示在屏幕(视频控制器->读取缓存信息->数模转换->显示器)

这是我今天学的东西,大家可以不用 理会我(如果我写的哪里有问题,可以指出来,也可以憋着)

来一段无关的主要代码,省略无关细节

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
//定义一个,着色管理器
GLShaderManager shaderManager;

//简单的批次容器
GLBatch triangleBatch;

// 顶点数组
GLfloat vVerts[] = {
-blockSize,-blockSize,0.0f,
blockSize,-blockSize,0.0f,
blockSize,blockSize,0.0f,
-blockSize,blockSize,0.0f
};

void SpecialKeys(int key, int x, int y){

// 可以添加 边缘碰撞,物理碰撞,回弹 等算法,
...

// 设置修改 RenderScene 中需要用到的基础数据
...

// 触发 glutDisplayFunc
glutPostRedisplay();
}

// 窗口大小改变的 回调
void changeSize(int w,int h){
// 设置视口
glViewport(0, 0, w, h);
}

// 渲染的 回调
void RenderScene(void){
// 清除缓存区
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT);

// typedef float M3DMatrix44f[16]; // A 4 X 4 matrix, column major (floats) - OpenGL style
M3DMatrix44f mFinalTransform, mTransfromMatrix, mRotationMartix;

// 平移矩阵
m3dTranslationMatrix44(M3DMatrix44f m, float x, float y, float z)

// 旋转矩阵
m3dRotationMatrix44(M3DMatrix44f, float angle, float x, float y, float z);

// 合并矩阵
m3dMatrixMultiply44(M3DMatrix44f product, const M3DMatrix44f a, const M3DMatrix44f b);

// 将矩阵结果 提交给固定着色器(平面着色器)中绘制
// enum GLT_STOCK_SHADER { GLT_SHADER_IDENTITY = 0, GLT_SHADER_FLAT, GLT_SHADER_SHADED, GLT_SHADER_DEFAULT_LIGHT, GLT_SHADER_POINT_LIGHT_DIFF,
// GLT_SHADER_TEXTURE_REPLACE, GLT_SHADER_TEXTURE_MODULATE, GLT_SHADER_TEXTURE_POINT_LIGHT_DIFF, GLT_SHADER_TEXTURE_RECT_REPLACE,GLT_SHADER_LAST };
// UseStockShader(GLT_STOCK_SHADER nShaderID, ...);
shaderManager.UseStockShader(GLT_SHADER_FLAT, mFinalTransform, vRed);

//
triangleBatch.Draw();

// 交换缓存区
glutSwapBuffers();
}

// 准备工作
void initGl(){
// Set working directoyr to /Resources on the Mac
// void gltSetWorkingDirectory(const char *szArgv);
gltSetWorkingDirectory(argv[0]);

//初始化GLUT库,
glutInit(&argc, argv);

/*
初始化双缓冲窗口,其中标志GLUT_DOUBLE、GLUT_RGBA、GLUT_DEPTH、GLUT_STENCIL分别指
双缓冲窗口、RGBA颜色模式、深度测试、模板缓冲区

--GLUT_DOUBLE`:双缓存窗口,是指绘图命令实际上是离屏缓存区执行的,然后迅速转换成窗口视图,这种方式,经常用来生成动画效果;
--GLUT_DEPTH`:标志将一个深度缓存区分配为显示的一部分,因此我们能够执行深度测试;
--GLUT_STENCIL`:确保我们也会有一个可用的模板缓存区。
深度、模板测试后面会细致讲到
*/
glutInitDisplayMode(GLUT_DOUBLE|GLUT_RGBA|GLUT_DEPTH|GLUT_STENCIL);

//GLUT窗口大小、窗口标题
glutInitWindowSize(800, 600);
glutCreateWindow("Triangle");


// glutReshapeFunc(void (*func)(int width, int height))
glutReshapeFunc(changeSize);

// 注册显示函数
// glutDisplayFunc(void (*func)(void))
glutDisplayFunc(RenderScene);

// glutSpecialFunc(void (*func)(int key, int x, int y))
glutSpecialFunc(SpecialKeys);


// GLUT window callback 还有很多其他的回调 等等...
glutKeyboardFunc(void (*func)(unsigned char key, int x, int y))
glutMouseFunc(void (*func)(int button, int state, int x, int y))
glutEntryFunc(void (*func)(int state))


// 设置渲染环境
glClearColor(0.98f, 0.40f, 0.7f, 1);
// 初始化固定管线,(后期学习自定义着色器)
shaderManager.InitializeStockShaders();

// Start populating the array 设置点的连接方式
// void Begin(GLenum primitive, GLuint nVerts, GLuint nTextureUnits = 0);
triangleBatch.Begin(GL_TRIANGLE_FAN, 4);

// void CopyVertexData3f(GLfloat *vVerts) { CopyVertexData3f((M3DVector3f *)(vVerts)); }
triangleBatch.CopyVertexData3f(vVerts);

// Tell the batch you are done
triangleBatch.End();

// 开启 死循环
glutMainLoop();
}

&

1
2


opengl 的单词

Open GL: 点、线、三角形

顶点数组:内存

顶点缓冲区:GPU显存

位图:像素点的数组,(一个像素点:RGBA * 4 = 4字节)

纹理数组:???

&

管线:工场流水线

固定管线:对应非常多固定摸具(固定着色器)

可编程管线:可以编程的摸具(GLSL编程)

&

着色器:shader – GPU执行的代码

顶点着色器:处理顶点的数据(1:位置,2:缩放/平移/旋转,3:2D/3D投影成2D数据)

片元着色器:处理所有像素的数据

&

固定着色器:系统的API方法

自定义着色器:GLSL代码

iOS GPU编程语言:GLSL、Metal SL

光栅化1系统调度GPU计算出顶点转片元的像素点、2附着颜色离屏渲染;

`顶点-》顶点着色器(点)-》图元装配(形状)-》光栅化-》???`

纹理:tga文件,压缩图片-》位图

混合:叠加像素点的计算,触发离屏渲染

变换矩阵:平移、缩放、旋转

投影矩阵:3D 坐标投影成2D坐标

&

投影方式:正投影(2D数据)、透视投影(3D数据)

视口:可以被看见的窗口,投影的效果

camera: 观察者视角位置

&

  • 2D笛卡尔坐标
  • 摄像机坐标系:以观察着
  • 物体坐标系:物体本身的坐标系,
  • 世界坐标系:
  • 规范坐标系:代码规范

&

显示器缓存区:双缓存区交换 swapBuffers()

open gl 没有窗口显示功能,需依赖GLTools,显示到窗口上

GLTools:操作系统提供的 Open gl 对接工具,


了解相关方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
UseStockShader(着色器)

// 刷新周期回调:
initDisplayMode,

//屏幕尺寸变化回调:
initWindowSize,

GLfloat,GLMainLoop, GLBatch

//清理初始化数据:
glClear, glClearColor(颜色)

//试图大小:
glViewport

markdown

加粗

斜体

下划线

代码

删除线

超链接

图片链接

标题1

标题2

标题3

标题4

标题5
标题6

段落

表格 a b c
1 a1 b1 c1
2 a2 b2 c2
1
2
#代码块
cd ..

$内联公式$

$$
公式块
$$

引用

爱因斯坦

  1. 有序列表a
  2. 有序列表b
  3. 有序列表c
  • 无序列表x

  • 无序列表y

  • 无序列表z

  • 任务列表t1

  • 无序列表t2