OpenGL Frame Buffer Object (FBO)

OpenGL学习:


1.OpenGL介绍:

OpenGL uses the prefix gl for core OpenGL commands and glu for commands in OpenGL Utility Library,OpenGL constants begin with GL_ and use all capital letters

OpenGL使用gl前缀来表示OpenGL核心命令,使用glu前缀来表示OpenglGL Utility库中的命令,使用大写GL_表示常量。

2.状态机:

OpenGL是一个状态机,模式和属性会一直保持直到被改变。大多数的状态变量都可以被glEnable()和glDisable()来打开和关闭。

也可以用gllsEnabled()来进行状态查询。你可以将一个状态变量的集合通过glPushAttrib()或glPopAttrib()保存或重新装载到属性栈中。

参数GL_ALL_ATTRIB_BITS可以用来保存或者重新装载状态。栈长度在标准OpenGL中至少为16.

3.glBegin()和glEnd()

为了画一些几何基元,你可以在glBegin()HeglEnd()之间指定一个顶点数据序列,这个方法会立即被调用。

OpenGL中有10中基元:GL_POINTS, GL_LINES, GL_LINE_STRIP, GL_LINE_LOOP, GL_TRIANGLES, GL_TRIANGLE_STRIP, GL_TRIANGLE_FAN, GL_QUADS, GL_QUAD_STRIP, and GL_POLYGON

4.glFlush()&glFinish()

和PC的IO buffer类似,OpenGL命令不是立即被执行。包括网络buffer和图像加速器本身,所有命令会先被存储在buffer中,在buffer满的时候再执行。举个例子,如果一个应用在网络上执行,在一个单独的包中发送一个指令集合会比每次发送一条命令要更为高效。

glFlush()清空这些buffer中的所有命令并强制所有绑定的命令立即执行而不是等待buffer被填满。因此glFlush()能够保证这个点的所有OpenGL命令能够在调用glFlush()之后的有限时间内执行完成。并且glFlush()不会等待前面的命令执行完成所以可能会立即(结束opengl指令)返回到程序中。所以即使前面的命令没有结束,你也可以自由地发送更多的命令

glFinish()会像glFlush一样清空buffer并且强制命令开始执行,但是glFinish()会阻塞其他OpenGL命令并且会等待所有命令执行完成。通常,glFinish()不会(结束opengl指令)返回到程序中知道所有显式调用的命令被执行完成。它可能会用来同步任务或者计算确定的OpenGL指令消耗了多少时间。

5.OpenGL Rendering Pipeline

Display List

Display list 是一系列的被存储起来即将被执行的OpenGL 命令。所有的数据,基元和像素数据都可以被存储在display list中。当命令和数据被缓冲到display list中的时候可以提高性能。当OpenGL 程序在网络上运行的时候,你可以通过display list减少数据传输量。因为display list是服务端状态的一部分并且存在于服务器中,客户端每次只需要发送一次命令和数据给服务端的displaylist就可以了。

vertex Operation

每个顶点和普通坐标都可以被GL_MODELVIEW矩阵转换(从物体坐标到裁剪坐标)。同时,如果开启了光照效果,每个顶点的光照计算是在转换后的顶点和普通数据上进行的。光照计算会更新顶点的颜色。

Primitive Assembly

在顶点操作之后,图元(点、线、面)会再一次被project matrix进行转换然后被视角剪切平面切割;从眼睛坐标到剪切坐标。在此之后,有w引发的角度划分和视口变换被应用以用于将3D场景贴到窗口空间坐标,最后要做的是当透视触发开启的时候进行透视除法测试。

Pixel Transfer Operation

在像素从客户端的内存中被解压(读取)之后,数据会经过缩放、偏移、映射和嵌位的过程。这些操作被称为像素转换操作。转换结果存储在纹理内存或直接栅格化到片段中。

Texture Memory

纹理图像会被加载到使用于几何对象上的纹理内存中

Raterization

光栅化是将几何图元和像素数据转换成片段的过程。片段是一个包含颜色、深度、线宽、点坐标和抗锯齿计算类型的矩形数组。如果阴影类型为GL_FILL,那么多边形的内部像素区域就会在这个阶段被填充。每个片段都对应frame buffer中的一个像素

Fragment Operation

片段操作

这是将片段转换到像素以用到frame buffer 上的最后一个过程。这个过程的第一步是产生纹理影像元件,一个纹理元素从纹理内存中产生并被应用到每个片段上。然后雾化计算被应用。这之后跟随有几个片段测试Scissor Test ⇒ Alpha Test ⇒ Stencil Test ⇒ Depth Test. 最后进行blending, dithering, logical operation 等位操作过程,实际的像素数据被存储到了framebuffer。

回顾

OpenGL可以glGet*()和glisEnabled()命令返回大多数的当前状态和信息。

此外,,你可以从framebuffer中通过glReadPixels()从frame buffer中读取一个矩形区域,通过glRenderMode(GL_FEEDBACK)获取转换后的顶点数据。glCopyPixels()不会讲像素数据返回到指定的系统内存,而是将其返回给另一个framebuffer,比如从前台buffer到后台buffer


6.OpenGL Transformation

在光栅化之前。几何数据诸如顶点坐标和普通向量通过顶点运算和图元装配操作在OpenGL 管道中进行转换。


Object Coordinates(物体坐标)

Object Coordinates是物体的本地坐标,是物体在未经任何转换之前的初始坐标和方位。为了转换物体,通常使用glRotatef(),glTranslatef(),glScalef()分别进行旋转,平移和缩放三种类型的转换。


Eye Coordinates(视点坐标)

Eye Coordinates是由GL_MODELVIEW矩阵和物体坐标相乘得到。物体会从物体空间通过OpenGL的GL_MODELVIEW矩阵被变换到视点坐标。GL_MODELVIEW矩阵是视图矩阵模型矩阵的点乘(Mview * Mmodel)。模型矩阵进行的是从物体空间(boject space)到世界空间(world space)的变换,视图矩阵进行的是从世界坐标(world space)到视点空间(eye space)的变换


注意OpenGL中没有独立的Camera(view)Matrix。因此为了模拟camera或者view的变换,场景(3D模型和光照)必须以view矩阵的逆进行变换。

换句话说,在视点坐标系中,OpenGL 定义camera默认位于(0,0,0)并且面向-Z轴方向,并且不能被变换


法向量通常从物体坐标变换到视点坐标以进行光照计算。注意法向量的转换方式和其他向量不同,它是GL MODELVIEW的逆矩阵的转置和法向量的乘积。


Clip Coordinates

前面视点坐标已经和GL_PROJECTION 矩阵相乘,变成了裁剪坐标。GL_PROJECTION矩阵定义了视锥体,顶点数据如何投射到屏幕上(正交还是透视),被称为裁剪坐标的结果是顶点(x,y,z)和±w比较进行裁剪得到。

 

Normalized Device Coordinates (NDC)

规格化设备坐标是为了便于图形处理,引入的一个与设备无关的坐标系,采用一种无量纲的单位代替设备坐标,当图形输出时,在转换为具体的设备坐标,采用规格化设备坐标系好处事:
用户的图形数据经转换成规格化设备坐标系中的值。
使应用程序与图形设备隔离开,增加了应用程序的可移植性

将裁剪坐标除以w就得到了规范化设备坐标。其三个轴上的值都规范化至-1到1之间。

Window Coordinates(Screen Coordinates)

将NDC做viewport变换就得到了窗口坐标。NDC被缩放和平移以适应要渲染的屏幕。窗口坐标最终被传递给OpengGL管道的光栅化阶段以将其变成片段(fragment)

glViewport()命令用来定义图像映射到的区域中(实际)要被渲染的矩形区域。glDepthRange()用来决定窗口坐标系的z轴值。窗口坐标由以上两个函数的参数得到。

glViewport(x, y, w, h); 
glDepthRange(n, f);



viewport变换公式仅仅是由NDC和窗口坐标之间的线性关系获得:



总结:

原始坐标与模型矩阵相乘(转到world space)以及与视图矩阵相乘(转到eye space)之后得到视点坐标。视点坐标再与视锥体矩阵(project matrix)相乘就得到了裁剪坐标。将裁剪坐标投射到屏幕上之前可以做透视除法得到NDC,最后可以将NDC经缩放和平移投射到要渲染的屏幕上得到窗口坐标。再辅以viewport和DepthRange设置得到最终效果。


7.矩阵详解

Model-View Matrix(GL_MODELVIEW 模型-视图矩阵)

GL_MODELVIEW矩阵是将视图矩阵和模型矩阵结合成一个矩阵。



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值