图元

一、基础管线

OpenGL 中图元只不过是顶点的集合以预定义的方式结合在一起。
管线分为2个部分:上半部分是客户机端,下半部分是服务器端。
服务器和客户端是功能和运行上都是异步的,它们是各自独立的软件或硬件块。


  • 客户端是存储在 CPU 存储器中的,并且在应用程序中执行,或者在主系统内存的驱动程序中执行。驱动程序会将渲染命令和数组组合起来,发送给服务器执行!(在一台典型的个人计算机上,服务器实际上就是图形加速卡上的硬件和内存)
  • 服务器和客户机在功能上也是异步的。它们是各自独立的软件块或硬件块。我们是希望它们2个端都尽量在不停的工作。客户端不断的把数据块和命令块组合在一起输送到缓冲区,然后缓冲区就会发送到服务器执行。
  • 如果服务器停止工作等待客户机,或者客户机停止工作来等待服务器做好接受更多的命令和准备,我们把这种情况称为管线停滞

二、着色器

渲染过程,必备的2个着色器“顶点着色器”和“片元着色器”。
上图的Vertex Shader(顶点着⾊色器器) 和 Fragment Shader(⽚片段着⾊色器器)。

  • 着⾊器是使⽤GLSL编写的程序,看起来与C语⾔非常类似。着⾊器必须从源代码中编译和链 接在⼀起。最终准备就绪的着色器程序
  • 顶点着⾊器-->处理从客户机输⼊的数据、应⽤变换、进⾏其他的类型的数学运算来计算光照效果、位移、颜⾊色值等等。(**为了渲染共有3个顶点的三角形,顶点着⾊器将执⾏3次,也就是为了每个顶点执行⼀次)在⽬前的硬件上有多个执行单元同时运行,就意味着所有的3个顶点可以同时进行处理!
  • 图上(primitive Assembly)说明的是:3个顶点已经组合在一起,而三角形已经逐个片段的进行了光栅化。每个片段通过执行 片元着色器 进行填充。片元着色器会输出我们将屏幕上看到的最终颜色值。

三、3种向 OpenGL 着色器传递渲染数据的方法

  • 属性
  • Uniform
  • 纹理

3.1 属性

属性:就是对一个顶点都要作改变的数据元素。实际上,顶点位置本身就是一个属性。属性就可以浮点类型、整形、布尔类型。

  • 属性总是以四维向量的形势进行内部存储的,即使我们不会使用所有的4个分量。一个顶点位置可能存储 (x,y,z),将占有4个分量中的3个。
  • 实际上如果是在平面情况下:只要在 xy 平面上就能绘制,那么z分量就自动设置为0。
  • 属性还可以是:纹理坐标、颜色值、光照计算表面法线
  • 在顶点程序 (shader渲染)可以代表你想要的任何意义。因为都是你设定的。
  • 属性会从本地客户机内存中复制在图形硬件中的一个缓冲区上。这些属性只提供给顶点着色器使用,对于片元着色器没有太大意义。
  • 声明 这些属性对每个顶点都要作改变,但并不意味着它们的值不能重复。通常情况下,它们都是不一样的,但有可能整个数组都是同一值的情况。

3.2 Uniform 值

通过设置 Uniform 变量就紧接着发送一个图元批次命令。Uniform 变量实际上可以无限地使用,设置一个应用于整个表面的单个颜色值。还可以设置一个时间值。在每次渲染某种类型的顶点动画时修改它。

  • 注意 这里的 uniform 变量每个批次改变一次,而不是每个顶点改变一次。
  • uniform 变量最常见的应用是在顶点渲染中设置变换矩阵
  • 与属性相同点:可以是浮点型、整数、布尔值
  • 与属性不同点:顶点着色器和片元着色器都可以使用 uniform 变量。uniform 变量还可以是标量类型、矢量类型、uniform 矩阵。

3.3 纹理

简单的说,纹理就是矩形的数据数组。例如颜色、亮度数据等,之所以复杂,是因为矩形纹理可以映射到非矩形的区域。

四、创建坐标系

GLFrustum frustum;
void SetOrthographic(GLfloat xMin, GLfloat xMax, GLfloat yMin, GLfloat yMax, GLfloat zMin, GLfloat zMax);

五、透视投影

GLFrustum frustum;
void SetPerspective(float fFov, float fAspect, float fNear, float fFar);

透视投影会进行透视除法对距离观察者很远的对象进行缩放和收缩。在投影到屏幕之后,视景体背面与视景体正面的宽度测量标准不同。
上图所示: 平头截体(frustum)的几何体,它的观察方向是从金字塔的尖端到宽阔端。观察者的视点与金字塔的尖端拉开一定距离。

GLFrustum类通过setPerspective ⽅方法为我们构建⼀一个平截头体。
参数:
fFov:垂直⽅方向上的视场⻆角度
fAspect:窗⼝口的宽度与⾼高度的纵横⽐比
fNear:近裁剪⾯面距离
fFar:远裁剪⾯面距离
纵横⽐比 = 宽(w)/⾼高(h)

 CLFrustum::SetPerspective(float fFov,float fAspect,float fNear
,float fFar);

六、存储着色器

6.1 GLShaderManager 的初始化

  GLShaderManager shaderManager;
  shaderManager.InitializeStockShaders();
  shaderManager.UseStockShader(参数列表) // 使用      

6.2 GLShaderManager 属性

标识符 描述符
GLT_ATTRIBUTE_VERTEX 3分量(x,y,z)顶点位置
GLT_ATTRIBUTE_COLOR 4分量(r,g,b,a)颜色值
GLT_ATTRIBUTE_NORMAL 3分量(x,y,z)表面法线
GLT_ATTRIBUTE_TEXTUREO 第一对2分量(s,t)纹理坐标
GLT_ATTRIBUTE_TEXTURE1 第二对2分量(s,t)纹理坐标

存储着色器为每一个变量都使用一致的内部变量命名规则和相同的属性槽。

6.3 GLShaderManager 的 uniform 值

  • 一般情况,要对几何图形进行渲染,我们需要给对象递交属性矩阵,首先要绑定我们要使用的着色程序上,并提供程序的 uniform 值。但是 GLShanderManager 类可以暂时为我们完成工作。
  • useStockShader 函数会选择一个存储着色器并提供这个着色器的 unifrom 值。
GLShaderManager::UserStockShader(GLeunm shader ...);
  • 单位着色器 只是简单地使用默认笛卡尔坐标系(坐标范围(-1.0,1.0))。所有的片段都应用同一种颜色,几何图形为实心和为渲染的。 需要这种存储着色器一个属性: GLT_ATTRIBUTE_VERTEX (顶点分量)vColor[4] 需要的颜色

    GLShaderManager::UserStockShader(GLT_ATTRIBUTE_VERTEX,GLfloat vColor[4]);
    
  • 平面着色器 它将统一着色器进行拓展。允许为几何图形变换指定一个 4*4 变换矩阵。经常被统称为“模型视图投影矩阵”

    参数1:平面着色器
    参数2:允许变化的 4*4 矩阵

    GLShaderManager::UserStockShader(GLT_ATTRIBUTE_VERTEX,GLfloat vColor[4]);
    
  • 上色着色器 在几何图形中应用的变换矩阵。需要设置存储着色器的 GLT_ATTRIBUTE_VERTEX (顶点分量) 和 GLT_ATTRIBUTE_COLOR (颜色分量)2个属性。颜色值将被平滑地插入顶点之间(平滑着色)

    GLShaderManager::UserStockShader(GLT_SHADER_SHADED,GLfloat mvp[16]);
    
  • 默认光源着色器 这种着色器,是对象产生阴影的光照效果。需要设置存储着色器的GLT_ATTRIBUTE_VERTEX(顶点分量)GLT_ATTRIBUTE_NORMAL(表面法线)
    参数1:默认光源着色器
    参数2:模型视图矩阵
    参数3:投影矩阵
    参数4:颜色值

    GLShaderManager::UserStockShader(GLT_SHADER_DEFAULT_LIGHT,GLfloat   mvMatrix[16],GLfloat pMatrix[16],GLfloat vColor[4]);
    
  • 点光源着色器 点光源着色器和默认光源着色器很相似,区别在于,光源位置是特定的。同样需要设置存储着色器的GLT_ATTRIBUTE_VERTEX(顶点分量)GLT_ATTRIBUTE_NORMAL(表面法线)
    参数1:点光源着色器
    参数2:模型视图矩阵
    参数3:投影矩阵
    参数4:视点坐标光源位置
    参数5:颜色值

    GLShaderManager::UserStockShader(GLT_SHADER_DEFAULT_LIGHT_DIEF,GLfloat  mvMatrix[16],GLfloat pMatrix[16],GLfloat vLightPos[3],GLfloat vColor[4]);
    
  • 纹理替换矩阵 着色器通过给定的模型视图投影矩阵,使用绑定到nTextureUnit(纹理单元)指定纹理单元的纹理对几何图形进行变化。
    片段颜色:是直接从纹理样本中直接获取的。
    需要设置存储着色器的 GLT_ATTRIBUTE_VERTEX(顶点分量)GLT_ATTRIBUTE_NORMAL(表面法 线)

    GLShaderManager::UserStockShader(GLT_SHADER_TEXTURE_REPLACE,GLfloat     mvMatrix[16],GLintnTextureUnit);
    
  • 纹理调整着色器 将纹理调整着色器乘以一个取自纹理单元 nTextureUnit的纹理。需要设置存储着色器的 GLT_ATTRIBUTE_VERTEX(顶点分量)GLT_ATTRIBUTE_TEXTURE0(纹理坐标)

    GLShaderManager::UserStockShader(GLT_SHADER_TEXTURE_MODULATE,GLfloat
      mvMatrix[16],GLfloat vColor[4],GLint nTextureUnit);
    
  • 纹理光源着色器 将一个纹理通过漫反射照明计算机进行调整(相乘)。光线在视觉空间中的位置是给定的。需要设置存储着色器的 GLT_ATTRIBUTE_VERTEX(顶点分量)GLT_ATTRIBUTE_TEXTURE0(纹理坐标)GLT_ATTRIBUTE_NORMAL(表面法线)
    参数1:纹理光源着色器
    参数2:投影矩阵
    参数3:视觉空间中的光源位置
    参数4:几何图形的基本色
    参数5:将要使用的纹理单元

    GLShaderManager::UserStockShader(GLT_SHADER_TEXTURE_MODULATE,GLfloat
    mvMatrix[16],GLfloat vColor[4],GLint nTextureUnit);
    

七、OpenGL 图元

点、线、线带、线环、三角形、三角形金字塔、三角形带、三角形扇

//修改点的大小
glPointSize(4.0f);
//设置点的大小范围,点和点之间的距离
GLfloat sizes[2] = {2.0f,4.0f};
GLfloat stepSize = 1.0f;
//获取点的大小范围和步长
glGetFloatv(GL_POINT_SIZE_RANGE,sizes);
glGetFloatv(GL_POINT_GRAULRITY,&stepSize);
//3.通过使用程序点大小模式设置点大小
glEnable(GL_PROGAM_POINT_SIZE);
//GLSL程序
gl_PointSize = 5.0f;

八、GLBatch 容器(帮助类)

void GLBatch::Begin(GLenum primitive, GLuint nVerts, GLuint nTextureUnits = 0);
void GLBatch::CopyNormalDataf(M3DVector3f *vNorms);
void GLBatch::CopyColorData4f(M3DVector4f *vColors);
void GLBatch::CopyTexCoordData2f(M3DVector2f *vTexCoords, GLuint uiTextureLayer);
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,406评论 6 503
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,732评论 3 393
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 163,711评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,380评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,432评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,301评论 1 301
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,145评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,008评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,443评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,649评论 3 334
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,795评论 1 347
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,501评论 5 345
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,119评论 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,731评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,865评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,899评论 2 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,724评论 2 354

推荐阅读更多精彩内容