美文网首页
OpenGL架构及常见图元与简单使用

OpenGL架构及常见图元与简单使用

作者: 泽泽伐木类 | 来源:发表于2020-07-09 17:10 被阅读0次

OpenGL渲染架构

OpenGL渲染架构图

上图是根据自己的学习跟理解,简单绘制的一张结构图。从上图可以看出我们通过OpenGL API 来间接操作GPU

通道(传递数据的方式)

  • attribute 属性 (只能直接传递到顶点着色器,不能直接传递到片元着色器,需要间接访问)
    颜色数据
    顶点数据
    纹理坐标
    光栅法线
  • uniform 值 (相对固定,可以直接传递到片元着色器/顶点着色器)
    渲染矩阵(比如YUV->RGB 的转化矩阵)
  • texture Data (可以传递到顶点着色器/片元着色器)
    滤镜
    渲染图形
    像素填充->颜色填充

实际开发中我们可编程的部分是Vertex ShaderFragment 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种图元连接方式

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。

相关文章

网友评论

      本文标题:OpenGL架构及常见图元与简单使用

      本文链接:https://www.haomeiwen.com/subject/gzojcktx.html