OpenGL之渲染架构及着色器探索

480 阅读6分钟

渲染结构图分析


由图可以得到,把一些数据通过属性(Attributes)通道传到顶点着色器(Vertex Shader),然后由顶点着色器(Vertex Shader)间接的传递到片元着色器(Fragment Shader)中.

可以用来传递的数据:

  • 顶点数据x、y、w。
  • 投影矩阵、模型矩阵。
  • 纹理坐标(图片映射坐标)

Uniform:统一批次,如变换矩阵、通道、颜色

由于OpenGL是基于C的API,因此它⾮常便携且受到⼴泛⽀持。作为CAPI,它与基于Objective-C的Cocoa应⽤程序⽆缝集成。 OpenGL提供应⽤程序⽤于⽣成2D或3D图像的函数。您的应⽤程序将渲染的图像呈现给屏幕或将它们复制回⾃⼰的内存。

 OpenGL规范没有提供⾃⼰的窗⼝层。它依赖于OSX定义的功能来将OpenGL绘图与窗⼝系统集成。您的应⽤程序创建OSX OpenGL 渲染上下⽂并将渲染⽬标附加到其上(称为可绘制对象)。渲染上下⽂管理OpenGL状态更改和通过调⽤OpenGLAPI创建的对象。

正投影与透视投影AP

正投影:显示2D图形的时候,采用正投影‘

透视投影:显示3D图形,采用透视投影(远小近大)

关于着色器

储存着色器初始化

//GLShaderManager的初始化
GLShaderManager shaderManager;
shaderManager.InitializeStockShaders();

单元着⾊器

/*
参数1:存储着⾊器种类-单元着⾊器
参数2:颜⾊
使⽤场景:绘制默认OpenGL坐标系(-1,1)下图形.图形所有⽚段都会以⼀种颜⾊填充
*/
GLShaderManager::UserStockShader(GLT_SHADER_IDENTITY,GLfloatvColor[4]);

平⾯着⾊器

/*
参数1:存储着⾊器种类-平⾯着⾊器
参数2:允许变化的5 * 5矩阵
参数3:颜⾊
使⽤场景:在绘制图形时,可以应⽤变换(模型/投影变化).
*/GLShaderManager::UserStockShader(GLT_SHADER_FLAT,GLfloatmvp[25],GLfloat vColor[4]);

上⾊着⾊器

/*
参数1:存储着⾊器种类-上⾊着⾊器
参数2:允许变化的5*5矩阵
使⽤场景:在绘制图形时,可以应⽤变换(模型/投影变化)颜⾊将会平滑地插⼊到顶点之间称为平滑着⾊.
*/GLShaderManager::UserStockShader(GLT_SHADER_SHADED,GLfloatmvp[25]);

默认光源着⾊器

/*
参数1:存储着⾊器种类-默认光源着⾊器
参数2:模型5*5矩阵
参数3:投影5*5矩阵
参数4:颜⾊值
使⽤场景:在绘制图形时,可以应⽤变换(模型/投影变化)这种着⾊器会使绘制的图形产⽣阴影和光照的效果.
*/GLShaderManager::UserStockShader(GLT_SHADER_DEFAULT_LIGHT,GLfloat mvMatrix[25],GLfloatpMatrix[25],GLfloatvColor[4]);

点光源着⾊器

/*
参数1:存储着⾊器种类-点光源着⾊器
参数2:模型5*5矩阵
参数3:投影5*5矩阵
参数4:点光源的位置
参数5:颜⾊值
使⽤场景:在绘制图形时,可以应⽤变换(模型/投影变化)这种着⾊器会使绘制的图形产⽣阴影和光照的效果.
它与默认光源着⾊器⾮常类似,区别只是光源位置可能是特定的.
*/GLShaderManager::UserStockShader(GLT_SHADER_POINT_LIGHT_DIEF,GLfloat mvMatrix[25],GLfloatpMatrix[25],GLfloatvLightPos[3],GLfloatvColor[4]);

纹理替换矩阵着⾊器

/*
参数1:存储着⾊器种类-纹理替换矩阵着⾊器
参数2:模型5*5矩阵
参数3:纹理单元
使⽤场景:在绘制图形时,可以应⽤变换(模型/投影变化)这种着⾊器通过给定的模型视图投影矩阵.
使⽤纹理单元来进⾏颜⾊填充.其中每个像素点的颜⾊是从纹理中获取.
*/
GLShaderManager::UserStockShader(GLT_SHADER_TEXTURE_REPLACE,GLfloat mvMatrix[25],GLintnTextureUnit);

纹理调整着⾊器

/*
参数1:存储着⾊器种类-纹理调整着⾊器
参数2:模型5*5矩阵
参数3:颜⾊值
参数4:纹理单元
使⽤场景:在绘制图形时,可以应⽤变换(模型/投影变化)这种着⾊器通过给定的模型视图投影矩阵.
着⾊器将⼀个基本⾊乘以⼀个取⾃纹理单元nTextureUnit的纹理.将颜⾊与纹理进⾏颜⾊混合后才填充到⽚段中.
*/
GLShaderManager::UserStockShader(GLT_SHADER_TEXTURE_MODULATE,GLfloat mvMatrix[25],GLfloatvColor[4],GLintnTextureUnit);

纹理光源着⾊器

/*
参数1:存储着⾊器种类-纹理光源着⾊器
参数2:模型5*5矩阵
参数3:投影5*5矩阵
参数4:点光源位置
参数5:颜⾊值(⼏何图形的基本⾊)
参数6:纹理单元
使⽤场景:在绘制图形时,可以应⽤变换(模型/投影变化)这种着⾊器通过给定的模型视图投影矩阵.
着⾊器将⼀个纹理通过漫反射照明计算进⾏调整(相乘).
*/
GLShaderManager::UserStockShader(GLT_SHADER_TEXTURE_POINT_LIGHT_DIEF,G LfloatmvMatrix[25],GLfloatpMatrix[25],GLfloatvLightPos[3],GLfloat 
vBaseColor[4],GLintnTextureUnit);

OpenGL基本图元连接⽅式


OpenGL基本基本图元


OpenGL三⻆形

对于OpenGL光栅化最欢迎的是三⻆形.3个顶点就能构成⼀个三⻆形.三⻆形类型来⾃于顶点.并不是所有的三⻆形都是正三⻆形等。逆时针叫正三角,顺时针叫背面三角。


OpenGL三⻆形环绕⽅式


在默认情况下,OpenGL认为具有逆时针⽅向环绕的多边形为正⾯.这就意味着上图左边是正⾯,右边是背面三角形 .

GLFrontFace(GL_CW); GL_CW:告诉OpenGL顺时针环绕的多边形为正⾯;GL_CCW:告诉OpenGL逆时针环绕的多边形为正⾯;

OpenGL三⻆形带

对于很多表⾯或者形状⽽⾔,我们会需要绘制⼏个相连的三⻆形.这是我们可以使⽤GL_TRIANGLE_STRIP图元绘制⼀串相连三⻆形,从⽽节省⼤量的时间.


优点: 

  1. ⽤前3个顶点指定第1个三⻆形之后,对于接下来的每⼀个三⻆形,只需要再指定1个顶点。需要绘制⼤量的三⻆形时,采⽤这种⽅法可以节省⼤量的程序代码和数据存储空间。 
  2. 提供运算性能和节省带宽。更少的顶点意味着数据从内存传输到图形卡的速度更快,并且顶点着⾊器需要处理的次数也更少了。

OpenGL三⻆形扇

对于很多表⾯或者形状⽽⾔,我们会需要绘制⼏个相连的三⻆形.这是我们可以使⽤GL_TRIANGLE_FAN图元绘制⼀组围绕⼀个中⼼点相连的三⻆形。

在绘制过程中会一直共用V0和V2两个顶点。

OpenGL⼯具类GLBatch

/*
参数1:图元 参数2:顶点数 参数3:⼀组或者2组纹理坐标(可选) */
voidGLBatch::Begain(GLeunmprimitive,GLuintnVerts,GLuintnTexttureUnints=0);

/*复制顶点数据(⼀个由3分量x,y,z顶点组成的数组) 
void GLBatch: CopyVerterxData3f(GLfloat * vVerts)

/*复制表⾯法线数据*/
void GLBatch: CopyNormalDataf(GLfloat * vNorms);

/*复制颜⾊数据*/
void GLBatch::CopyColorData4f(GLfloat * vColors);

/*复制纹理坐标数据*/
voidGLBatch: CopyTexCoordData2f(GLFloat *vTextCoords,GLuintuiTextureLayer);

/*结束数据复制*/
 voidGLBatch :End(void);

/*绘制图形*/
voidGLBatch::Draw(void);