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