1. 固定着色器
1.1 固定存储着色器的初始化
//定义一个,着色管理器
GLShaderManager shaderManager;
//固定着色器的初始化
shaderManager.InitializeStockShaders();
1.2 固定存储着色器的类型
1.2.1 单元着色器
- 代码编写
//颜色设置四个参数分别表示RGBA
GLfloat vColor[] = { 0.3f, 0.6f, 0.1f, 1.0f };
//使用单元着色器绘制图形
shaderManager.UseStockShader(GLT_SHADER_IDENTITY, vColor);
- 使用场景:绘制默认OpenGL坐标系(-1, 1)下的图形,图形所有片段都会以一种颜色填充。
1.2.2 平面着色器
- 代码片段
//模型投影矩阵
GLfloat mvpMatrix[16];
//颜色值
GLfloat vColor[4];
//使用平面着色器
shaderManager.UseStockShader(GLT_SHADER_FLAT, mvpMatrix, vColor);
- 使用场景:在绘制图形时,可以应用变换(模型/投影变化)。
1.2.3 上色着色器
- 代码编写
//允许变化的4*4矩阵
GLfloat mvp[16];
//使用上色着色器绘制图形
shaderManager.UseStockShader(GLT_SHADER_SHADED, mvp);
- 使用场景:在绘制图形时,可以应用变换(模型/投影变化),这种着色器会将颜色平滑的插入到顶点之间,也称为平滑着色。
1.2.4 默认光源着色器
- 代码编写
//模型矩阵
GLfloat mvMatrix[16];
//投影矩阵
GLfloat pMatrix[16];
//颜色值
GLfloat vColor[4];
//使用默认光源(平行光)着色器绘制图形
shaderManager.UseStockShader(GLT_SHADER_DEFAULT_LIGHT, mvMatrix, pMatrix, vColor);
- 使用场景:在绘制图形时,可以应用变换(模型/投影变化),这种着色器会使绘制的图像产生阴影和光照的效果。
1.2.5 点光源着色器
- 代码编写
//模型矩阵
GLfloat mvMatrix[16];
//投影矩阵
GLfloat pMatrix[16];
//点光源的位置
GLfloat vLightPosition[3];
//颜色值
GLfloat vColor[4];
shaderManager.UseStockShader(GLT_SHADER_POINT_LIGHT_DIFF, mvMatrix, pMatrix, vColor);
- 使用场景:在绘制图形时,可以应用变换(模型/投影变化),这种着色器会使绘制的图像产生阴影和光照的效果,它与默认光源着色器非常类似,区别只是光源位置可能是特定的。
1.2.6 纹理替换矩阵着色器
- 代码编写
//模型投影矩阵
GLfloat mvpMatrix[16];
//纹理单元
GLint nTextureUnit;
//使用纹理替换矩阵着色器
shaderManager.UseStockShader(GLT_SHADER_TEXTURE_REPLACE, mvpMatrix, nTextureUnit);
- 使用场景:在绘制图形时,可以应用变换(模型/投影变化),这种着色器通过给定的模型视图投影矩阵,使用纹理单元来进行颜色填充,其中每个像素点的颜色是从纹理中获取。
1.2.7 纹理调整着色器
- 代码编写
//模型投影矩阵
GLfloat mvpMatrix[16];
//颜色值
GLfloat vColor[4];
//纹理单元
GLint nTextureUnit;
//使用纹理调整着色器
shaderManager.UseStockShader(GLT_SHADER_TEXTURE_MODULATE, mvpMatrix, vColor, nTextureUnit);
- 使用场景:在绘制图形时,可以应用变换(模型/投影变化),这种着色器通过给定的模型视图投影矩阵,将一个基本色乘以一个取自纹理单元nTextureUnit的纹理,将颜色与纹理进行颜色混合后才填充到片段中。
1.2.8 纹理光源着色器
- 代码编写
//模型矩阵
GLfloat mvMatrix[16];
//投影矩阵
GLfloat pMatrix[16];
//点光源的位置
GLfloat vLightPosition[3];
//颜色值
GLfloat vBaseColor[4];
//纹理单元
GLint nTextureUnit = 0;
//使用纹理光源着色器
shaderManager.UseStockShader(GLT_SHADER_TEXTURE_POINT_LIGHT_DIFF, mvMatrix, pMatrix, vLightPosition, vBaseColor, nTextureUnit);
- 使用场景:在绘制图形时,可以应用变换(模型/投影变化),这种着色器通过给定的模型视图投影矩阵,着色器将一个纹理通过漫反射照明计算进行调整(相乘)。
2 基本图元
2.1 常用基本图元
基本图元
2.2 每种图元解释
2.2.1 点(GL_POINTS)
- 点图元是OpenGL中最基本的图元类型,当设置为此类型时,渲染顶点数据的时候将会以默认为1的像素点的长度渲染传入的顶点数据映射到屏幕上的坐标位置。
- 可以使用以下种方式改变点的大小
//第一种:最简单也是最常⽤的 4.0f,表示点的⼤⼩
glPointSize(4.0f);
//第二种:设置点的⼤⼩范围和点与点之间的间隔
GLfloat sizes[2] = {2.0f,4.0f};
GLfloat step = 1.0f;
//获取点⼤⼩范围和最⼩步⻓
glGetFloatv(GL_POINT_SIZE_RANGE ,sizes);
glGetFloatv(GL_POINT_GRAULARITY ,&step);
//第三种:通过使⽤程序点⼤⼩模式来设置点⼤⼩
glEnable(GL_PROGRAM_POINT_SIZE);
//第四种:这种模式下允许我们通过编程在顶点着⾊器或⼏何着⾊器中设置点⼤⼩。着⾊器内建变量:gl_PointSize,并且可以在着⾊器源码直接写
gl_PointSize = 5.0
注意:在图形渲染之后,要将点的大小恢复成初始值1,这样才不会影响其他图形的绘制。
2.2.2 线段
- 每对顶点定义一个线段(GL_LINES)
- 这种类型的图元设置,会将顶点数据中的点以两两结合的方式映射到屏幕上以线段的方式连接显示
- 改变线段宽度
//设置线段宽度
glLineWidth(2.5f);
注意:在渲染线段之后,要重新设置线段宽度为默认值1。
- 一个从第一个顶点依次经过每一个后续顶点而绘制的线条(GL_LINE_STRIP)
- 这种类型的图元设置,会将顶点数据中的点按照顺序映射到屏幕上以一条线段的方式连接显示
- 闭合线条(GL_LINE_LOOP)
- 与GL_LILNE_STRIP类似,但会在最后将尾部顶点与头顶点也连接起来。
2.2.3 三角形
- 每三个顶点定义一个新的三角形(GL_TRIANGLES)
- 共用一条带(strip)上的顶点的一组三角形(GL_TRIANGLE_STRIP)
对于很多表面或形状而言,我们会需要绘制几个相连的三角形,这是我们可以使用GL_TRIANGLE_STRIP图元绘制一串相连三角形从而节省大量时间。 - 以一个圆点为中心呈扇形排列,共用相邻顶点的一组三角形(GL_TRIANGLE_FAN)
对于很多表面或形状而言,我们会需要绘制几个相连的三角形,这是我们可以使用GL_TRIANGLE_FAN图元绘制一组围绕一个中心点相连的三角形。 - 使用GL_TRIANGLE_STRIP或GL_TRIANGLE_FAN绘制图形的优点:
- 用前三个顶点指定一个三角形后,对于接下来的每个三角形,只需要再指定一个顶点,需要绘制大量的三角形时,采用这种方式可以节省大量的程序代码和数据存储空间。
- 提升运算性能和节省带宽。更少的顶点意味着数据从内存传输到图形显卡的速度更快,并且顶点着色器需要处理的次数也更少了。
-
三角形环绕方式
如下图所示:在绘制第⼀个三⻆形时,线条是按照从V0到V1,再到V2。最后再回到V0的⼀个闭合三⻆形。 这个是沿着顶点顺时针⽅向。这种顺序与⽅向结合来指定顶点的⽅式称为环绕。
三角形环绕方式
- 在OpenGL中,认为具有逆时针方向环绕的多边形为正面,这就意味着上图左边是正面,右边是反面,OpenGL中,默认是以逆时针环绕的多边形为正面的。
- 如果想要改变这个设置可以调用glFrontFace(GL_CW);这个函数,传入参数为GL_CW时是告诉OpenGL以顺时针环绕的多边形为正面,传入参数为GL_CCW是告诉OpenGL以逆时针环绕的多边形为正面。
2.3 基本图元的使用
使用GLBatch简单容器类
方法以及其传入参数解释
//参数1:图元
//参数2:顶点数
//参数3:⼀组或者2组纹理坐标(可选)
void GLBatch::Begain(GLeunm primitive,GLuint nVerts,GLuint nTexttureUnints = 0);
//复制顶点数据(⼀个由3分量x,y,z顶点组成的数组)
void GLBatch::CopyVerterxData3f(GLfloat *vVerts);
//复制表⾯法线数据
void GLBatch::CopyNormalDataf(GLfloat *vNorms);
//复制颜⾊数据
void GLBatch::CopyColorData4f(GLfloat *vColors);
//复制纹理坐标数据
void GLBatch::CopyTexCoordData2f(GLFloat *vTextCoords, GLuint uiTextureLayer);
//结束数据复制
void GLBatch::End(void);
//绘制图形
void GLBatch::Draw(void);