ogl总结

固定管线OpenGL 1.0 robust
渲染rendering:根据模型数据创建图像的过程
渲染管线(pipeline):在渲染处理中会顺序执行一系列操作,这个处理阶段叫做渲染管线
模型model:根据几何图元创建的物体
几何图元:点,直线,多边形等,都是通过定点指定的


管线操作;
1. 指定几何对象
立即模式:a.一次一个定点
 b.使用定点数组
显示列表模式:数据放于显示列表中
glNewList, glEndList, glCallList


2. 顶点处理操作,每个顶点分别是单独处理 per-vertex operations 【顶点着色器处理】
a.顶点变换:根据模型视图和投影矩阵变换,
b.光照计算和法线变换和法线规格化
c.纹理坐标变换(纹理矩阵)
d.材质状态:纹理坐标生成
输入:每个顶点的属性特征,输出:变换后的顶点数据


3.图元组装(顶点数据->图元) 【几何着色器】
顶点处理之后,及其全部属性都已经被确定.
顶点将会根据应用程序给定的【图元规则】如GL_POINTS,GL_TRIANGLES被组装成图元


4.图元处理(裁剪 消隐)
a. 裁剪操作,将图元与用户定义的裁剪平面,即glClipPlane和模型投影矩阵所建立的视景比较.这将会裁剪且丢弃位于视景
和【裁剪平面】外部的图元.不在处理他们
   gFrustum()【平截头体】指定棱台形的视景物,用于裁剪变换,在之前要指定glMatrixMode(GL_PROJECTION)
b. 如果采用[透视投影],那么将会对每个顶点(x,y,z)坐标分别除以齐次坐标w
Perspective Projection
c. [视口变换]将顶点坐标变换至窗口坐标
将视景体内投射的物体显示在二维的视口平面上.由glViewport()的定义来决定
d. 执行[消隐]操作  剔除(cull)根据设置的条件来舍弃一些固定朝向的面


5.光栅化操作,栅格化操作 Rasterization
a.图元处理传过来的数据,被分解成更小的单元并对应帧缓冲区的各个像素.被称作片元.一个片元可能包含窗口左边、
深度、颜色、纹理坐标等属性. => fragment表示可以被渲染到屏幕上的像素 = 图元上的顶点通过插值得到
b. 片元的属性是由图元上顶点数据等经过【插值】而确定的.这里生成的片元将会包含主颜色和次颜色.
glShadeMode()函数的作用将会在这里体现.即使用插值(平滑着色)或者使用最后一个顶点颜色(平面着色)
c. 点宽,线宽,多边形模式,正面背面等一些特征也将是在这个阶段发生作用.
d. 【反走样】也是这个阶段起作用.改善图像中线段图形的锯齿让其更平滑


6. 片元处理 (主要是取颜色)【FragmentShader】
输入:光栅化处理后生成的Fragment,color,深度值,模板值作为输入
a. 上纹理:通过纹理坐标取得纹理内存中相对应的颜色.
b. 雾化:通过片元距离当前视点位置修改颜色
c. 颜色汇总:区别于混合. 将纹理,主定义的颜色,雾化的颜色,次颜色光照阶段计算的颜色 汇总一起


7. 逐个片元的操作. 添加新的过滤条件或者新的生产条件进行处理
所有的一些测试 
ownership像素所有权测试:测试某个像素是否对用户可见或者被重叠窗口所阻挡
裁剪(glScissor):定义附加裁剪平面进行裁剪
模板测试(glStencilFunc):通过测试的片段像素会被保存到模板缓冲区,没通过的会被过滤掉,想模板筛子一样起到过滤的作用
深度测试(glDephtFunc):计算决定遮挡关系
Alpha测试(glAlphaFunc):alpha值满足特定值的像素才能被通过,该功能可用混合替代,但是alpha的效率更高
混合(glBlendFunc):颜色混合
Dithering抖动: 颜色平滑处理,解决颜色精度不够大而导致的颜色剧变问题
这些操作将会最后影响其在帧缓冲区的颜色值
咋话之前需要加上drawD区域
8. 帧缓冲操作
a. 这个阶段执行帧缓冲的写入等操作..最后产生了显示出来的像素
glColorMask. glStrncilMask glDepthMask glClearDepht glClearStencil glClearColor等将在这个阶段影响写入值


可编程管线可以替换的功能 OpenGL 2.0
在着色器编程领域..可实现
Vertex Shader 替换 顶点处理阶段
Fragment Shader(片元着色器或者像素着色器) 替换 片元处理阶段
Geometry Shader(几何着色器) 替换 图元组装阶段




万向节锁:两个轴旋转到同一个方向上去了,两个轴平行了, 因此比原来少了一维
四元数quaternion,解决了因旋转导致万向节锁的问题


glColor4f(1.0f,1.0f,1.0f,0.5f);   0.0全透,1.0不透明
颜色模式:平面着色和光滑着色对整个三维景观进行着色
光照模式:4种,可以设置模型表面的反射特性
图像效果增强:
【反走样】用于改善图像中线段图形的锯齿让其更平滑
【混合】用于处理模型的半透明效果
【雾化】使得影像从视点到远处逐渐褪色
双缓存(double buffer)
投影有两种:正交投影和透视投影 投影后显示在定义的viewport中


向量的点乘dot product  用于计算向量在另一向量上的投影 a dot b = |a|x|b|cos@
向量的叉乘cross product 用于计算向量组成平面的法线方向 |a cross b| = |a|x|b|sin@ 方向由右手定则确定
不支持交换律!交换法线向量就反向了
-----------------------------------------------------------------------
一、视点变换即:指定物体在世界坐标系中的摆放位置,
glLoadIdentity()【重置模型观察矩阵】即将视点移到屏幕的中心位置,
glBegin()和glEnd(),glVertex()中指定点是相对于glTranslatef(x,y,z)移动后的新原点来画图形
二、模型变换, glTranslatef(),glRotatef(),glScalef()
三、投影变换,由glFrustum()指定的视景体决定在其外多余的部分裁剪掉
四、视口变换,由glViewport(),视口的长宽比总是等于视景体裁切面的长宽比,如果比例不相等图像就会变形

-----------------------------------------------------------------------
正交投影(Orthographic Projection)
void glOrtho(),void gluOrtho2D(),三维和2维的正交投影函数用于施工,指定的是长方体视景体
透视投影(Perspective Projection)
void glFrustum(),创建棱柱形的视景体,void gluPerspective()
-----------------------------------------------------------------------
三维裁剪变化包括:
A.【视景体裁剪】,glMatrixMode(GL_PROJECTION),glLoadIdentity(),glFrustum()/gluPerspective()
B.【附加平面裁剪, glEnable(GL_CLIP_PLANEi),glClipPlane(GLenum plane, Const GLdouble *equation)】
Cyan/puple
-----------------------------------------------------------------------
简单光照模型,最多可以设置8个光源 LIGHT7
辐射光(EmittedLight)直接从物体发出,并且不受任何光源的影响
环境光(Ambient Light)像无影灯一样的光,可以均匀的照射到物体的各个面上
漫反射(DiffuseLight) 可以形成影子的光线,垂直于物体时比倾斜时更明亮
镜面光(SpecularLight) 用于产生反射效果的光线,,有个镜面指数的设置
A创建光源:Light Source
GLfloat light_position[] = {1.0, 1.0, 1.0, 0.0};
GLfloat light_ambient[] = {0.0, 0.0, 0.0, 1.0};
void glLightfv(GL_LIGHT0, GL_POSITION, light_position);//光源号,指定属性,指定值
void glLightfv(GL_LIGHT0, GL_AMBIENT, light_ambient);// 指定0号AMBIENT属性
启用光照:glEnable(GL_LIGHTING),glEnable(GL_LIGHT0)


B明暗处理:
 平面明暗处理Flat Shading:glShadeModel(GL_FLAT)用单一颜色进行处理
 光滑明暗处理Gourand/Smooth Shading:glShadeModel(GL_SMOOTH)用许多不同颜色处理,插值用的是双线性插值
先通过三角形顶点插值算出交线两端点的【光强值】,在通过两个交点值插值算出任意一点的值
C材质颜色:
openGL用材料对光三原色的反射率来近似定义材料的颜色
对【环境光】与【漫反射光】的反射程度决定了材料的颜色
材质定义:
void glMaterial{if}[v](GLenum face , GLenum pname, TYPE param);//GL_FRONT、GL_BACK、GL_FRONT_AND_BACK
//face 指材质应用到物体的哪个面,指定一个特定的材质,特定材质的具体数值
eg: GLfloat mat_ambient[] = {0.8,0.8, 0.8, 1.0};
glMaterialfv(GL_FRONT, GL_AMBIENT, mat_ambient); // 创建材质,指定


材质RGB值和光源RGB值的混合关系,对应部分的乘积结果
光源(LR,LG,LB) + 材质(MR,MG,MB) = 物体显示的颜色值(LR*MR, LG*MG, LB*MB);
光源1(R1,G1,B1) + 光源2(R2,G2,B2) = 总光源值(R1+R2, G1+G2, B1+B2);//任一成分的值大于1则约减到1.0(超出设备所能显示的亮度了)
eg: light_diffuse[]*mat_diffuse[],漫反射属性的最终效果
---------------------------------
全局环境光,独立于任何特定的光源所提供的环境光
GLfloat lmodel_ambient[] = {0.2, 0.2, 0.2, 1.0};
glLightModelfv(GLLIGHT_MODEL_AMBIENT, lmodel_ambient);
设置近视点与无穷远视点
视点位置能影响镜面高光,顶点的高光强度依赖于顶点法向量,从顶点到光源的方向和从顶点到视点的方向
glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_TRUE);
glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_FALSE);//设置光源视点为无穷远
启动双面光照计算
glLightModeli(LIGHT_MODEL_TWO_SIDE, GL_TRUE);关闭GL_FALSE
光源位置和衰减
 GLfloat light_position[] = {1.0, 1.0, 1.0, 0.0};//{x,y,z,w}
 glLightfv(GL_LIGHT0, GL_POSITION, light_position);
无穷远,定向光源,无衰减...当w值为0的时候
近光源,定位光源,有衰减...当w值不为0的时候,衰减=光源的发光量*衰减因子(包括常量\线性\平方三个衰减因子)
GL_CONSTANT_ATTENUATION/GL_LIENEAR_ATTENUATION/GL_QUADRATIC_ATTENUATION
-----------------------------------------------------------------------
OpenGL纹理:
纹理映射只能在RGBA方式下执行,不能应用于颜色表方式
2D纹理定义:
void glTexImage2D(GL_TEXTURE_2D, 0, 4, ImageWidth, ImageHeight,
0, GL_RGBA, GL_UNSIGNED_BYTE, &Image[0][0][0]);
纹理控制:
void glTexParameter{if}[v](GLenum pname, TYPE param);


设置纹理环绕模式:重复/截取
glTexParameteri(GL_TEXTURE_WRAP_S/T/R, GL_REPEAT/GL_CLAMP/GL_CLAMP_TO_EDGE/GL_CLAMP_TO_BORDER)
纹理过滤/滤波:最邻近过滤、线性过滤
根据一个拉伸或缩放的纹理贴图计算颜色片段的过程,叫做(Texture Filtering),
所以有GL_TEXTURE_MIN/MAG_FILTER这两个过滤器设置其过滤模式
glTexParameter*(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILETER, GL_NEAREST/LINEAR);

映射方式:三种纹理映射方式
void glTexEnv{if}[v](GLenum target, GLenum pname, TYPE param);
eg;target必须是GL_TEXTURE_ENV,第二个pname是GL_TEXTURE_ENV_MODE,第三个可以是:GL_DECAL/GL_MODULATE/GL_BLEND
第二个参数是GL_TEXTURE_ENV_COLOR,第三个参数是包含四个浮点数的数组(包含RGBA分量)


12.5纹理坐标;
A....点指定:
{s, t, r, q}区分于顶点坐标,r没有使用忽略掉
物体坐标点的顺序要和纹理坐标点的映射位置对应,不然会出现意向不到的结果
eg: glBegin(GL_QUADS);
glTexCoord2f(0.0, 0.0); glVertex3f(-2.0, -1.0, 0.0);
      glTexCoord2f(0.0, 1.0); glVertex3f(-2.0, 1.0, 0.0);
      glTexCoord2f(1.0, 1.0); glVertex3f(0.0, 1.0, 0.0);
      glTexCoord2f(1.0, 0.0); glVertex3f(0.0, -1.0, 0.0);
glEnd();
glFlush();


GLubyte Image[ImageWidth][ImageHeight][3];//指定width和height的方法
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);//有什么作用
    /* 定义纹理 */
    glTexImage2D(GL_TEXTURE_2D, 0, 3, ImageWidth,
      ImageHeight, 0, GL_RGB, GL_UNSIGNED_BYTE, &Image[0][0][0]);


    /* 控制滤波 */
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);


    /* 说明映射方式*/
    glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);


    /* 启动纹理映射 */
    glEnable(GL_TEXTURE_2D);
B.....坐标自动产生:
void glTextGen{if}[v]()

混合:
注意光照也可以对光源和材质的反射效果进行混合计算
Rs*Sr+Rd*Dr, Gs*Sg+Gd*Dg, Bs*Sb+Bd*Db, As*Sa+Ad*Da)
启用:glEnable(GL_BLEND)
通过设置混合方程里的源因子和目的因子来达到混合效果
void glBlendFunc(GLenum sfactor,GLenum dfactor)


反走样:
antialiasing,离散数学代表的图像和真实图像间存在的误差
比如直线或光滑曲线呈现的锯齿、彩色花纹失去原有的形状和色彩等。
这种锯齿就叫走样
启用反走样:
glEnable(GL_POINT\GL_LINE_SMOOTH\GL_POLYGON_SMOOTH)
可用glHint()提供一个图像质量提示。如果在RGBA模式下则必须启用混合

雾化:
离视点远的物体会变得模糊,看起更真实
haze mist smoke pollution,浓度,距离与变淡速度,颜色均可设置
glEnable(GL_FOG);
    {
// 选择控制浓度和颜色的雾方程
      glFogi (GL_FOG_MODE, GL_LINEAR);// GL_EXP(缺省)、GL_EXP2、GL_LINEAR
      glFogfv (GL_FOG_COLOR, fogColor);// RGBA模式下可使用
      glFogf (GL_FOG_START, 3.0);
      glFogf (GL_FOG_END,15.0);
      glHint (GL_FOG_HINT, GL_DONT_CARE);
      glClearColor(0.3, 0.3, 0.3, 1.0);
    }


帧缓存:
颜色缓存: 可以保存颜色索引,也可以是RGBA颜色数据。支持立体视图有左、右缓存,支持双缓存有前台、后台缓存,至少有左前两个
深度缓存:深度用视点到物体的距离来度量,决定遮挡关系,叫Z-BUFFER
模板stencil: 可以保持屏幕上某些部位的图形不变,其他部位任然可以进行图形绘制,eg:移动的汽车内部视图
累积缓存:值保存RGBA颜色数据,不能保存颜色索引数据


【缓存清除】清屏或者清除缓存的开销比绘制的时候多得多
glClearColor()
选择了要清除的缓存及设置其清除值后,就可以调用glClear()来请求硬件完成清除的操作了。这个清除函数为:
【void glClearColor(GLclampf red,GLclampf green,GLclampf blue,GLclampf alpha);/
 void glClearDepth(GLclampd depth);/
 void glClearStencil(GLint s);】
 
void glClear(Glbitfield mask);
mask的取值 GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT|GL_ACCUM_BUFFER_BIT


动画,通过双缓存可以实现动画
glxSwapBuffers()特定的交换函数


三维绘图流程
1.定义颜色格式和缓冲模式,设置光源,设置材质,定义投影方式
2.定义与windows接口的系统函数
  定义绘图窗口的位置,定义绘图窗口的标题,定义绘图窗口改变时窗口的刷新函数,定义空闲回调,
  定义场景绘制函数 void auxMainLoop(name)
-----------------------------------------------------------------------
蓝皮书
-----------------------------------------------------------------------
可编程管线
属性,uniform,纹理三种方式给着色器传递渲染数据方法
counterclockwise
clockwise
opengl默认逆时针方向环绕的多边形是正面 glFrontFace(GL_CW/GL_CCW)来进行改变


表面剔除:
glCullFace(GL_BACK/GL_FRONT/GL_FRONT_AND_BACK);
glEnable(GL_CULL_FACE);
根据设置的条件来舍弃一些固定朝向的面
GL_FRONT/GL_BACK/GL_FRONT_AND_BACK,提高渲染效率
对正面和背面三角形进行区分的原因之一就是为了进行剔除CULL_FACE


深度测试:
实现真实视觉并提高性能
glutInitDisplayMode(GLUT_DOUBLE|GLUT_RGBA|GLUT_DEPTH)
glEnable(GL_DEPTH_)
是一种高效消除隐藏表面的技术,由深度缓冲区完成,计算的时候加入Z值,绘制的时候对Z值进行比较
绘制的时候通过【颠倒油画法】:即先绘制离观察者近的对象,再绘制较远的对象。这样深度测试将消除
那些应该被已存在像素覆盖的像素,将节省存储器带宽!


裁剪:
默认情况裁剪框和窗口一样大,并且不会进行裁剪测试。【没看懂】
glEnable(GL_SCISSOR_TEST)
void glScissor(x,y,width,height);//定义裁剪矩形区域


混合:
新的颜色与已经存在的颜色值在颜色缓冲区中进行组合
如果没开混合,深度测试会根据深度缓冲区的z值比较(即离定义的裁剪平面的远近),进行简单的颜色覆盖还是丢弃
如果开启了,会根据开启的混合方式,进行颜色的组合,得到不同的特殊效果
混合方程式:
Cf = Cs*S + Cd*D //混合因子S和D
    glBlendFunc(s,d)指定,见表3.3
可修改混合方程式:
glBlendEquation(mode) //见表3.4,加,减,反序减,最小,最大


混合的另一用途抗锯齿:主要是点和线的支持 glEnable(GL_POINT_SMOOTH/GL_LINE_SMOOTH/GL_POLYGON_SMOOTH)
多重采样(multisampling):解决混合不支持的对实心多边形边缘锯齿的优化,额外的内存和处理器开销
首先要请求获得一个支持多重采样的帧缓冲区
glutInitDisplayMode(GLUT_DOUBLE|GLUT_RGBA|GLUT_DEPTH|GLUT)
glEnable(GL_MULTISAMPLE);
另外:如果启用了多重采样,点直线和多边形的平滑处理将被忽略,所以仅使用点直线的平滑处理的时候要关闭多重采样
eg: glDisable(GL_MULTISAMPLE);
glEnable(GL_POINT_SMOOTH);
//DRAW some smooth points
glDisable(GL_POINT_SMOOTH);
glEnable(GL_MULTISAMPLE);

视图变换:调整工作坐标系,随后的变换将基于新调整的坐标系进行
模型变换:对特定对象的移动,旋转,缩放
模型视图矩阵是在管线中这两步的组合
投影变换:定义视景体并创建了裁剪平面,透视近大远小的视觉效果
执行透视除法 /w,在图元装配阶段执行
视口变换:将二维投影映射到屏幕上某处的窗口上
正规矩阵可以从模型视图矩阵推导出来
-----------------------------------------------------------------------
 基本纹理 texturemapping
glGenTextures()
glBindTexture()
LoadTGATexture()
GL_LINEAR_MIPMAP_LINEAR:称为【三线性Mip贴图】
glTexParameteri(GL_TXTRUE_2D,GL_TEXTURE_BASE_LEVEL, 0);
glTexParameteri(GL_TXTRUE_2D,GL_TEXTURE_MAX_LEVEL, 4);
glGenerateMipmap()


【各向异性的过滤】:进行纹理过滤时考虑了观察角度
1、确认这种扩展是否得到支持
gltExtensionSupported("GL_EXT_texture_filter_anisotropic");
2、查询得到支持的各向异性过滤的最大数量
glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &fLargest);
3、设置想要应用的各向异性过滤的数量
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, fLargest);
纹理压缩:
-----------------------------------------------------------------------
shader
GLSL:
向量类型 vec2/3/4, i/u/bvec2/3/4
矩阵类型 mat2,3,4,mat2/3/4x2/3/4
存储限定符:in/out/inout(只能用于局部函数参数),uniform,const,in/out centroid
另外3个smooth一种透视方法来插值、flat表示不进行插值、noperspective指定非透视插值
smooth out vec3 vSmoothValue


着色器定义:
版本(#version 400),属性声明(由各种限定符指定),顶点动作(main)


shader文件的编译、绑定、连接:
流程 P174 蓝皮书


显示列表现在还用吗
模板测试(glStencilFunc):?


显示模式函数:
void auxInitDisplayMode(
AUX_DOUBLE | //双缓存
AUX_RGBA //RGBA
);


顶点照明:
float 顶点漫反射光强 = dot(点到光源的向量即光线方向向量,视觉空间表面法线向量 );//结果为-1.0----1.0即夹角的余弦,这两个向量都需要时单位长度的
顶点基于光线强度的光照颜色值  =  顶点漫反射光强 x 顶点的颜色值


WOX 空格唤出运行框


ADS光照模型:vVertexColor = vAmbientColor + vDiffuseColor + vSpecularColor;
环境光
vec3 AmbientColor = vAmbientMaterial * vAmbientLight;
漫反射光
float fDotProduct = max(0.0, dot(vNormal, vLightDir));
vec3 vDiffuseColor = vDiffuseMaterial * vDiffuseLight * fDotProduct;
镜面光
vec3 vReflection = reflect(-vLightDir, vEyeNormal);
float EyeReflectionAngle = max(0.0, dot(vEyeNormal, vReflection));
fSpec = pow(EyeReflectionAngle, shininess); // shininess 反光度越大反射高光区域越小
vec3 vSpecularColor = vSpecularLight * vSpecularMaterial * fSpec;


PS:镜面高光部分呈现星光模式,运动的时候会有明显闪烁。由于三角形之间的不连续造成的,不连续是由颜色值在空间中进行线性插值导致的。
   亮线实际就是三角形之间的缝隙。Phong着色可以改善,在顶点之间进行表面法线插值,不进行颜色值插值。


6.5访问纹理
uniform sampler2D colorMap; //采样器实际上就是一个整数,使用glUniform1i(iTextureUniform, 0);
vFragColor = texture(colorMap, vVaryingTexCoords.st);//colorMap指定是哪一张纹理,纹理生成的绑定号
glGenTextures(GLsizei n, GLuint* textures); //
eg: glGenTextures(1, &textureMap); // textureMap就给colorMap赋值
丢弃片段:
discard,停止片段着色运行,即放弃该片段后面的所有计算


-----------------------------------------------------------------------
纹理高级知识
基于距离的点大小变化:size = 平方根(1/(a + b*d + c*d^2));
矩形纹理和立方体纹理,多重纹理,点表面应用纹理实现粒子系统效果,纹理数组加载大量纹理。纹理代理,查询纹理内部表示形式
-----------------------------------------------------------------------
缓冲区对象
运动模糊motion blur
一个OpenGL窗口的表面长期以来一直被称作“帧缓冲区”


在帧缓冲区中复制数据:
blit 位块复制
void glBlitFramebuffer();
-----------------------------------------------------------------------
管线的终点


输入片段-->剪裁测试-> 多重采样->模板测试->深度缓冲测试->混合->逻辑操作->抖动测试-->到帧缓冲区


裁剪测试:glEnable(GL_SCISSOR_TEST)启动裁剪测试;glScissor(left, bottom, width, height)设置裁剪区域; 
多重采样:【需要花精力认真揣摩】
模板测试:想象成在一块硬纸板上裁剪下来一个图案,然后再找个镂空的部分在墙上喷涂出图像,只能接触到镂空那部分
glEnable(GL_STENCIL_TEST)启用; 
glStencilFuncSeparate()
glStencilOpSeparate()

深度测试:如果启用,深度测试失败,则片段将被销毁,该片段将不会被送往其他阶段
深度截取:默认是关闭的,相当于添加了一个近端和远端的剪切面,尽可能多的沿着Z轴方向【保留几何图形】。
用它来避免比近端近、比远端远的数据被裁剪掉。glEnable(GL_DEPTH_CLAMP);


混合:
设置混合方程式
glBlendEquation()
glBlendEquationSeparate();
混合函数:
glBlendFuncSeparate()
glBlendFunc()
glBlendColor()

抖动Dither测试:生成平滑的颜色过渡
用硬件对从一种可表示的颜色到下一步骤的【过度】进行混合的一种方法。默认情况是开启的,它能使渲染更加漂亮自然


//逻辑操作:不常用了,只是说GPU中任然支持这功能而已,S 逻辑操作 D


遮罩输出:
颜色:glColorMask(writeR,writeG,writeB),glColorMaski(colorBufIndex,writeR,writeG,writeB);
深度:glDepthMask(GL_TRUE/GL_FALSE);//开启关闭写入,写入就是可以往该缓冲区更新数据的意思
模板:glStencilMask(GLuint mask) ,对位段具体设定值,1为可写入0为不可写入
eg: GLuint mask = 0x0007;
glStencilMask(mask);
glStencilMaskSeparate(GL_BACK,mask);
-----------------------------------------------------------------------
开始编写练习
1. 查询扩展
GLint nNum;
glGetIntegerv(GL_NUM_EXTENSIONS, &nNum);
  获得特定扩展的名称
for(GLint i=0; i<nNum; i++)
{ if (strcmp("WGL_EXT_swap_control",(const char*)glGetStringi(GL_EXTENSIONS,i))

}
2. OpenGL错误
 glenum glGetError(void);
 返回值类型 GL_INVALID_ENUM/GL_INVALID_VALUE/GL_INVALID__OPERATION/GL_INVALID_MEMORY/GL_NO_ERROR


3. 确认版本
const GLubyte *glGetString(GLenum name)
4. 获取线索
执行的时候更偏重速度还是视觉质量
void glHint(GLenum target, GLenum mode);
eg: glHint(GL_LINE_SMOOTH_HINT/*GL_POINT_SMOOTH_HINT/GL_POLYGON_SMOOTH_HINT/GL_TEXTURE_COMPRESSION_HINT*/,
GL_FASTEST/*/GL_NICEST/GL_DONT_CARE*/);
5. 查询状态
void glEnable(GLenum capability);void glDisable(GLenum capability); GLboolean glIsEnable(GLenum capability);
glGetIntegerv(GLenum pname, GLint *params);//所有状态的初始状态值都可以通过get的不同版本拿到
-----------------------------------------------------------------------
定义视口:
原点位置在窗口坐标的左下角
glViewport(0,0,w,h);
glut:
首先setupRC()
进入一次changeSize回调
然后进入两次RenderScene回调
glutInit(&argc,argv);
glutInitDisplayMode(GLUT_DOUBLE|GLUT_RGBA|GLUT_DEPTH);

glutInitWindowSize(width,height);
glutCreateWindow("window_name");

GLenum err = glewInit();

glutReshapeFunc( void (* callback)( int, int ) );
void changeSize(int x, int y) // x win_width, y win_height;
{ glViewport( 0, 0, x, y );} // opengl的坐标原点在窗口左下角,设置视口尺寸,视口内容会缩放

glutDisplayFunc( void (* callback)( void ) );
void renderScene(void)
{
// Clear the window with current clearing color
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);

// rendering

// Flush drawing commands
glutSwapBuffers();
}


glutKeyboardFunc( void (* callback)( unsigned char, int, int ) );
void KeyPressFunc(unsigned char key, int x, int y)// key键盘按下的键码,x,y按键时候鼠标相对于窗口左上角的值
{
// dosome logic change


// Refresh the Window,just post a message
glutPostRedisplay();
}


glutMouseFunc( void (* callback)( int, int, int, int ) );//鼠标点击回调

glutCreateMenu(ProcessMenu);//glutCreateMenu( void (* callback)( int menu ) );
glutAddMenuEntry("Toggle depth test",1);
glutAddMenuEntry("Toggle cull backface",2);
glutAddMenuEntry("set Fill Mode",3);
glutAddMenuEntry("set Line Mode",3);


varying 用来传递顶点和片段着色器之间的过度值,比如说片段颜色,变换过的纹理坐标结果,eg:varying vec4 vFragColor
uniform    统一值用来传递各种计算矩阵,灯光颜色,等
attribute   顶点坐标法顶点法线向量,纹理坐标等每个都要进行变换的输入


顶点照明:先算出基于各顶点光线强度的光照颜色值,在顶点之间对这些颜色进行平滑着色
法向矩阵(normal matrix)作为一个统一值3x3,这个值仅包含模型视图矩阵的旋转分量.
vec3 vEyeNormal = normalMatrix * vNormal,得到表面法线的视觉坐标
float diff = max(0.0, dot(vEyeNormal, vLightDir)); // vLightDir为单位矩阵


mNormalMatrix[0] = mvMatrix[0].xyz;
mNormalMatrix[1] = mvMatrix[1].xyz;
mNormalMatrix[2] = mvMatrix[2].xyz; // mNormalMatrix[]仅是模型视图矩阵的旋转分量
vec3 vEyeNormal = normalize(mNormalMatrix * vNormal);
vec3 vLightDir = vec3(0.0, 0.0, 1.0); 
float diff = max(0.0, dot(vEyeNormal, vLightDir)); 


// 数学库矩阵函数
m3dLoadIdentity44(m)//将M设置为单位矩阵
translation信息在列主序的12,13,14位置,3x3的矩阵可以完全包含伸缩旋转和形变信息


m3dTranslationMatrix44()
m3dRotationMatrix44()
m3dMatrixMultiply44()


gltMakeSphere(sphereBatch, 3.0, 10, 20);
// Torus
gltMakeTorus(torusBatch, 3.0f, 0.75f, 15, 15);
// Cylinder
gltMakeCylinder(cylinderBatch, 2.0f, 2.0f, 3.0f, 13, 2);
// Cone
gltMakeCylinder(coneBatch, 2.0f, 0.0f, 3.0f, 13, 2);
// Disk
gltMakeDisk(diskBatch, 1.5f, 3.0f, 13, 3);


viewFrustum.SetPerspective(35.0f, float(w)/float(h), 1.0f, 500.0f)


PS: uniform variables cannot be specified between calls to glBegin and glEnd, so they can change at most once per primitive.
varying variables is passed from vertex processor to fragment processor
    The vertex processor output (special output variables and user-defined and built-in varying variables) is sent to subsequent stages of processing that are defined exactly the same as they are for fixed-function processing: primitive assembly, user clipping, frustum clipping, perspective divide, viewport mapping, polygon offset, polygon mode, shade mode, and culling.


-------------------------------------------------------------------------------------
second Edition
-------------------------------------------------------------------------------------
shader 实例
建议:
编码前分析问题的实质
循序渐进的增加shader的复杂性和难度
迭代开发,测试ok之后简化,在开发
最后为朴素与简洁奋斗,选择最简洁的算法和方式,因为其可读可维护性好
开发成模块化,让模块之间可以组合: exploit modularity
性能的考虑:
考虑计算频率:app的CPU计算后当uniform传入比如sqrt,过度不明显的可以在vp里做比如需要线性插值的结果,镜面反射在fp里做
分析算法行为
多用内建函数:由图形硬件实现的,比较快
多用vectors做计算:!但是注意别造成内存的浪费
使用Logs:log查询函数经常会有错误或者性能警告
glGetShaderInfoLog() glGetProgramInforLog()


顶点着色器里面变量:
  gl_Position;必须写入gl_PointSize;gl_ClipVertex;可以被写入
  gl_Position = u_mvpMatrix * a_vertexPosition;
简单光照模型:
-------------------------------------------------------------------------------------
模拟固定管线
-------------------------------------------------------------------------------------
directional lights方向光的齐次坐标w为0,因为点位为无穷远
point lights 点光源是聚光灯spotlight在0到180度的cutoff


一个顶点颜色的两个部分:
primary color:是自发光、环境光、漫反射的combination
secondary color:仅仅包含镜面反射光
如果没有启用主副模式,则主颜色就包括4种光的混合
镜面高光是在纹理计算过后再应用的?


雾化:
可以是一个标准的顶点属性(gl_FrogCoord),也可以是视觉坐标距离(由z的绝对值指定)
雾化是线性插值的:f= (end-z)/(end-start); 都是在eye-coordinate中
fog = (gl_Fog.end - gl_FogFragCoord)*gl_Frog.scale;// gl_Frog.scale=1/(end-start);
也可以用自定义的指数效果更逼真:f = e^(density.z);
fog = exp(-gl_Fog.density * gl_FogFragCoord);
或者是2次的指数形式:f = e^(density.z)2;
fog = exp(-gl_Fog.density * gl_Fog.density *
  gl_FogFragCoord * gl_FogFragCoord);
最后的雾化颜色可以和fragment color进行混合


简单的: gl_ClipVertex = gl_ModelViewMatrix * gl_Vertex;
转换顶点到eye-coordinate space 


纹理方式应用:
GL_REPLACE: color = texture2D(tex0, gl_TexCoord[0].xy);
GL_MODULATE: color *= texture2D(tex0, gl_TexCoord[0].xy); //调节
GL_DECAL:
vec4 texture = texture2D(tex0, gl_TexCoord[0].xy);
vec3 col = mix(color.rgb, texture.rgb, texture.a); //贴花 mix( x, y, a) --> x*(1-a) + y*a;
color = vec4(col, color.a);
GL_BLEND: 
vec4 texture = texture2D(tex0, gl_TexCoord[0].xy);
vec3 col = mix(color.rgb, gl_TextureEnvColor[0].rgb, texture.rgb);
color = vec4(col, color.a * texture.a);
GL_ADD:
vec4 texture = texture2D(tex0, gl_TexCoord[0].xy);
color.rgb += texture.rgb;
color.a   *= texture.a;
color = clamp(color, 0.0, 1.0);


存储纹理:
选择并激活纹理单元 glActiveTexture()
创建纹理对象,并绑定它到激活的纹理单元上glBindTexture()
设置各种纹理对象的参数 glTexParameter() //wrapping behavior and filtering modes
定义纹理等相关函数 glTexImage2D()
赋值:lightLoc = glGetUniformLocation(programObj, "LightPosition");
 glUniform3f(lightLoc, 0.0, 0.0. 4.0);
多重纹理例子:
激活多个纹理单元,每个纹理都参与计算就是多重纹理


Procedural Texture shaders:算法长生纹理颜色值,11章,有利有弊,自己看着办
-------------------------------------------------------------------------------------
light:chapter 12
. A cubic interpolation method 
 Linear interpolation 
-------------------------------------------------------------------------------------
怎么提高程序的效率
一.能实现更多类型的算法,实现更真实的渲染,例如各种光照模型。没有做不到只有想不到
    固定管线是通过组合的方式来拼凑,效果很有限。
二.即使最基本的渲染,可编程管线对GPU的利用率更高,性能更好.因为GPU的资源可以动态的分配给各个stage
    eg.渲染大三角行多和小三角形多的场景对vertex和fragment stage的压力肯定不同.








what did you do yesterday?
what will you plan to do today?
is there anything blocking you or showing you down?
Before leaving, report you time in Hansoft!


encounter
penalty


ASK TO YOUR MENTOR OR LEADER TO REVIEW YOUR CODE BEFORE COMMIT
KEEP FUNCTION SIZE UNDER 1 SCREEN SIZE 




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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值