目录
基本图形硬件流水线设计
应⽤程序层 -> 硬件抽象层 -> 硬件层
一、应⽤层:
游戏和应⽤层软件开发⼈员为主体,通过调用API进行上层开发,不需要考虑移植性问题
应⽤程序层主要与内存,CPU打交道,诸如碰撞检测,场景图监理,视锥裁剪等经典算法在此阶段执⾏。在阶段的末端,几何体的数据(顶点坐标,法向量,纹理坐标,纹理)等通过数据总线传送到图形硬件
二、硬件抽象层:
抽象出硬件的加速功能,进⾏有利于应用层开发的封装,并向应⽤层开放API。
在这一层,我们⽬前使用的是DirectX与OpenGL。对于这一部分,主要是一些API等的调⽤。
三、硬件层:
将硬件驱动提供给抽象层,以实现抽象层加速功能的有效性。
硬件层在渲染流水线中最为复杂,也最为重要。可编程渲染流水线与固定渲染流水线的区别在于是否对着⾊器进⾏编程。
渲染流⽔线分为两种,其中一种为可编程渲染流⽔线。另外⼀种为固定渲染流⽔线。(也称 可编程管线或固定管线,管线就是流⽔线的意思)。渲染流水线可否编程,取决于程序猿能否在顶点着色器以及⽚段着⾊器上进⾏编码。而现在的渲染流水线,基本都是可编程的,当然,它们也⽀持固定渲染流水线的功能。
1、固定渲染流⽔线
2、可编程渲染流水线
GPU与CPU关系
GPU具有⾼并⾏的结构,所以在处理图形数据和复杂算法⽐CPU更加有效率
CPU在执⾏任务的时候,⼀个时刻只会处理⼀个数据,不存在真正意义上的并⾏,⽽GPU则有多个处理器核,在⼀个时刻可以并⾏处理多个数据.
CPU更擅长逻辑运算,比如if判断、for循环、中断调用。
GPU更擅长并行运算,比如无关联数据运算,各个像素点属并无关联,关于像素点的位置计算颜色计算GPU更擅长。
GLSL语法
一、变量与数据类型
布尔型:true,false
bool bDone = false;
有符号整型数据
int iValue = 42;
无符号整型数据
uint uiValue = 329u;
浮点型(只有单精度、没有双精度)
float fValule = 3.1415f
二、向量数据类型
向量声明
vec4 v1;
声明向量并且对其进行构造
vec4 v2 = vec4(1,2,3,4);
向量运算
vec4 v;
vec4 vOldPos = vec4(1,2,3,4);
vec4 vOffset = vec4(1,2,3,4);
v = vOldPOs;
v = vOldPos + vOffset;
v += vec4(10,10,10,10);
v = vOldPOs * vOffset;
v *= 5;
v.x = 3.0f;
v.xy = vec2(3.0f,4.0f);
v1.xyz = vec3(3,0f,4,0f,5.0f);
//可以通过颜色控制。r,g,b,a
v1.r = 3.0f;
v1.rgba = vec4(1.0f,1.0f,1.0f,1.0f);
//可以通过纹理坐标strq
v1.st = vec2(1.0f,0.0f);
//注意:赋值混合是不合法的
v1.st = v2.xt;//不可以
v1.st = v2.xy;//可以,没有意义
//向量支持调换(swizzle);2个或2个以上向量元素来进行交换
v1.rgba = v2.bgra;
v2.bgra = v1.rgba;
//赋值操作
v1.r = v2.b;
v1.g = v2.g;
v1.b = v2.r;
v1.a = v2.a;
//向量还支持一次性对所有分量操作
v1.x = vOtherVerex.x +5.0f;
v1.y = vOtherVerex.y +4.0f;
v1.z = vOtherVerex.z +3.0f;
v1.xyz = vOtherVerex.xyz + vec3(5.0f,4.0f,3.0f);
三、矩阵
//1.创建矩阵
mat4 m1,m2,m3;
//构造单元矩阵
mat4 m2 = mat4(1.0f,0.0f,0.0f,0.0f
0.0f,1.0f,0.0f,0.0f,
0.0f,0.0f,1.0f,0.0f,
0.0f,0.0f,0.0f,1.0f);
//构造单元矩阵
mat4 m4 = mat4(1.0f);
mat4 m3 = mat4( 0.5,0.5,0.5,0.5,
0.5,0.5,0.5,0.5,
0.5,0.5,0.5,0.5,
0.5,0.5,0.5,0.5,)
m1 = m2 * m3;
四、结构体
struct forStruct{
vec4 color;
float start;
float end;
}fogVar;
fogVar = fogStruct(vec4(1.0,0.0,0.0,1.0),
0.5,
2.0);
vec4 color = fogVar.color;
float start = fogVar.start;
五、数组
float floatArray[4];
vec4 vecArray[2];
//注意
float a[4] = float[](1.0,2.0,3.0,4.0);
vec2 c[2] = vec2[2](vec2(1.0,2.0),vec2(3.0,4.0));
六、函数
定义函数3个修饰符
in:(没有指定时,默认限定修饰符),传递进入函数中不能对其进行修改。
out:(函数返回时,可以将其修改)
inout:传入相应数值,并且可以在函数中进行修改
vec4 myFunc(inout float myFloat, out vec4 m1, mat4 m2){
//函数计算中
}
vec4 diffuse(vec3 normal ,vec3 light, vec4 baseColor) {
return baseColor * dot(normal,light);
}
//注意:GLSL函数没有递归!!!
七、控制语句
if(color.a < 0.25){
color *= color.a;
}else{
color = vec4(1.0,1.0,1.0,1.0);
}
//循环支持:while /do..while/ for
//但是 OpenGL ES 开发中尽量减少逻辑判断。尽量降低循环迭代使用
索引绘图
索引绘图纸关注顶点,然后通过顶点索引进行图元装配
图示一:
图示二:
代码示例
GLfloat attrArr[] =
{
-0.5f, 0.5f, 0.0f,//左上0
0.5f, 0.5f, 0.0f,//右上1
-0.5f, -0.5f, 0.0f,//左下2
0.5f, -0.5f, 0.0f,//右下3
0.0f, 0.0f, 1.0f,//顶点4
};
//(2).索引数组
GLuint indices[] =
{
0, 3, 2,
0, 1, 3,
0, 2, 4,
0, 4, 1,
2, 3, 4,
1, 4, 3,
};
//绘制
glDrawElements(GL_TRIANGLES, sizeof(indices) / sizeof(indices[0]), GL_UNSIGNED_INT, indices);
行者常至,为者常成!