OpenGL渲染架构

上图是根据自己的学习跟理解,简单绘制的一张结构图。从上图可以看出我们通过OpenGL API 来间接操作GPU
通道(传递数据的方式)
- attribute 属性 (只能直接传递到顶点着色器,不能直接传递到片元着色器,需要间接访问)
颜色数据
顶点数据
纹理坐标
光栅法线 - uniform 值 (相对固定,可以直接传递到片元着色器/顶点着色器)
渲染矩阵(比如YUV->RGB 的转化矩阵) - texture Data (可以传递到顶点着色器/片元着色器)
滤镜
渲染图形
像素填充->颜色填充
实际开发中我们可编程的部分是Vertex Shader
和Fragment Shader
,而Primitive Assembly
部分由OpenGL内部完成,无法干预。
正投影与透视投影
正投影:通常用来渲染2D效果,平行投影,1:1绘制,
透视投影:通常用来渲染3D效果,空间感(远小近大)
使用GLFrustum
类来创建投影方式:
/// 创建正投影矩阵
/// @param xMin x轴最小值
/// @param xMax x轴最大值
/// @param yMin y轴最小值
/// @param yMax y轴最大值
/// @param zMin z轴最小值
/// @param zMax z轴最大值
void SetOrthographic(GLfloat xMin, GLfloat xMax, GLfloat yMin, GLfloat yMax, GLfloat zMin, GLfloat zMax)
/// 创建透视投影矩阵
/// @param fFov 垂直⽅方向上的视场⻆角度
/// @param fAspect 窗⼝口的宽度与⾼高度的纵横⽐(w/h)
/// @param fNear 近裁剪⾯面距离
/// @param fFar 远裁剪⾯面距离
void SetPerspective(float fFov, float fAspect, float fNear, float fFar)
GLShaderManager存储着色管理器
GLShaderManager
:内部封装了很多着色器,通过枚举值及对应的参数来供开发者使用,我们不需要考虑着色器内部实现且无法自定义,只能在应用层操作。
初始化GLShaderManager
GLShaderManager shaderManager;
shaderManager.InitializeStockShaders();
使用单元着色器
GLShaderManager::UserStockShader(GLT_SHADER_IDENTITY,GLfloat vColor[4]);
**UserStockShader()**
// nShaderID 着色器名称(ID)
// id 对应 所需的参数
GLint UseStockShader(GLT_STOCK_SHADER nShaderID, ...);
其它着色器列举(主要是看下不同Shader_ID下对应的参数)
//单元着色器
GLShaderManager::UserStockShader(GLT_SHADER_IDENTITY,GLfloat vColor[4]);
//平面着色器
GLShaderManager::UserStockShader(GLT_SHADER_FLAT,GLfloat mvp[16],GLfloat vColor[4]);
//上色着色器
GLShaderManager::UserStockShader(GLT_SHADER_SHADED,GLfloat mvp[16]);
//默认光源着色器
GLShaderManager::UserStockShader(GLT_SHADER_DEFAULT_LIGHT,GLfloat mvMatrix[16],GLfloat pMatrix[16],GLfloat vColor[4]);
//点光源着色器
GLShaderManager::UserStockShader(GLT_SHADER_POINT_LIGHT_DIEF,GLfloat mvMatrix[16],GLfloat pMatrix[16],GLfloat vLightPos[3],GLfloat vColor[4]);
//纹理替换矩阵着色器
GLShaderManager::UserStockShader(GLT_SHADER_TEXTURE_REPLACE,GLfloat mvMatrix[16],GLint nTextureUnit);
//纹理调整着色器
GLShaderManager::UserStockShader(GLT_SHADER_TEXTURE_MODULATE,GLfloat mvMatrix[16],GLfloat vColor[4],GLint nTextureUnit);
//纹理光源着色器
GLShaderManager::UserStockShader(GLT_SHADER_TEXTURE_POINT_LIGHT_DIEF,G Lfloat mvMatrix[16],GLfloat pMatrix[16],GLfloat vLightPos[3],GLfloat vBaseColor[4],GLint nTextureUnit);
......
确实挺色的😻😍
OpenGL图元
图元即基本图形元素,是任何一个图形表达都是由若干不同的点、线、面图案或相同的图案循环组合而成的。这些点、线、面图案即为基本图形元素,简称图元。OpenGL中通过不过的图元来呈现不同的图像。
9种图元连接方式

图元 | 描述 |
---|---|
GL_POINTS | 每个顶点在屏幕上都是独立的点 |
GL_LINES | 每两个顶点定义一条线段,两两连接 |
GL_LINES_STRIP | 将每一个顶点依次连接的线 |
GL_LINE_LOOP | 将每一个顶点依次连接的闭合线段 |
GL_TRIANGLES | 每3个顶点定义一个三角形 |
GL_TRIANGLE_STRIP | 共用一个边上的顶点的一组三角形 |
GL_TRIANGLE_FAN | 以一个顶点作为原点设为中心呈扇形排列,共用相邻顶点的一组三角形 |
- 设置点的大小
glPointSize(4.0f);
- 设置线宽
glLineWidth(2.5f);
使用
在OpenGL中通过GLBatch
(是GLTools中包含的简单容器类)批次类来设置图元连接方式和组装顶点数据:
void GLBatch::Begain(GLeunm primitive,GLuint nVerts,GLuint nTexttureUnints = 0);
参数1:图元
参数2:顶点数 参数3:⼀一组或者2组纹理理坐标(可选)
//复制顶点数据(⼀一个由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);
- 使用
GL_POINTS
图元方式
GLfloat vCoast[9] = {
3,3,0,
0,3,0,
3,0,0
};
//GLBatch四部曲:Begin->Copy->End->Draw
//用点的形式
pointBatch.Begin(GL_POINTS, 3);
pointBatch.CopyVertexData3f(vCoast);
pointBatch.End();
这里省略了对其它图元的举例......具体看代码。
绘制
// Clear the window with current clearing color 清空当前缓存区
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
//压栈(记录状态)
modelViewMatrix.PushMatrix();
M3DMatrix44f mCamera;
cameraFrame.GetCameraMatrix(mCamera);
//矩阵乘以矩阵堆栈的顶部矩阵,相乘的结果随后简存储在堆栈的顶部
modelViewMatrix.MultMatrix(mCamera);
M3DMatrix44f mObjectFrame;
//只要使用 GetMatrix 函数就可以获取矩阵堆栈顶部的值,这个函数可以进行2次重载。用来使用GLShaderManager 的使用。或者是获取顶部矩阵的顶点副本数据
objectFrame.GetMatrix(mObjectFrame);
//矩阵乘以矩阵堆栈的顶部矩阵,相乘的结果随后简存储在堆栈的顶部
modelViewMatrix.MultMatrix(mObjectFrame);
/* GLShaderManager 中的Uniform 值——平面着色器
参数1:平面着色器
参数2:运行为几何图形变换指定一个 4 * 4变换矩阵
--transformPipeline.GetModelViewProjectionMatrix() 获取的
GetMatrix函数就可以获得矩阵堆栈顶部的值
参数3:颜色值(黑色)
*/
shaderManager.UseStockShader(GLT_SHADER_FLAT, transformPipeline.GetModelViewProjectionMatrix(), vBlack);
//设置点的大小
glPointSize(4.0f);
pointBatch.Draw();
glPointSize(1.0f);
//还原到以前的模型视图矩阵(单位矩阵)移除状态
modelViewMatrix.PopMatrix();
// 进行缓冲区交换,显示到屏幕
glutSwapBuffers();
矩阵
modelViewMatrix
:模型视图矩阵
projectionMatrix
:投影矩阵
transformPipeline
:变换管道
//设置需要相乘的矩阵
transformPipeline.SetMatrixStacks(GLMatrixStack &mModelView, GLMatrixStack &mProjection)
//返回相乘后的结果矩阵
M3DMatrix44f transformPipeline.GetModelViewProjectionMatrix()
从GLFrame
中获取矩阵:
GLFrame cameraFrame;
GLFrame objectFrame;
//获取观察者矩阵
M3DMatrix44f mCamera;
cameraFrame.GetCameraMatrix(mCamera);
//获取投影矩阵
M3DMatrix44f mObjectFrame;
objectFrame.GetMatrix(mObjectFrame);
矩阵的作用:让一个数据集做批量处理的方式。比如我们的例子中让顶点数据通过一个矩阵做一些批量的修改;比如一个YUV * 矩阵 = RGBA。
网友评论