opengl,OpenGL的特殊效果

OPENGL的特殊效果
1 融合 前面从未接触过透明或半透明的物体,因为我们从未启用过融合处理 所谓融合就是假设在RGBA模式下,源色为(Rs,Gs,Bs,As),目标色为 (Rd,Gd,Bd,Ad),源因子为(Sr,Sg,Sb,Sa),目的因子为(Dr,Dg,Db,Da) 则融合的最终效果为:(Rs*Sr+Rd*Dr,Gs*Sg+Gd*Dg,Bs*Sb+Bd*Db,As*Sa+Ad*Da) 然后再归一。公式挺复杂,不过仔细看看,跟平常的融合倒是定性一致。 关键就是如何设定融合因子(Sr,Sg,Sb,Sa)(Dr,Dg,Db,Da)来实现不同的融合效果 利用函数: void glBlendFunc(GLenum sfactor,GLenum dfactor); 其中两个参数可以取下面值: 取值 相关因子 计算后融合因子 GL_ZERO 源、目的 (0,0,0,0) GL_ONE 源、目的 (1,1,1,1) GL_DST_COLOR 源 (Rd,Gd,Bd,Ad) GL_SRC_COLOR 目的 (Rs,Gs,Bs,As) GL_ONE_MINUS_DST_COLOR 源 (1,1,1,1)-(Rd,Gd,Bd,Ad) GL_ONE_MINUS_SRC_COLOR 目的 (1,1,1,1)-(Rs,Gs,Bs,As) GL_SRC_ALPHA 源、目的 (As,As,As,As) GL_ONE_MINUS_SRC_ALPHA 源、目的 (1,1,1,1)-(As,As,As,As) GL_DST_ALPHA 源、目的 (Ad,Ad,Ad,Ad) GL_ONE_MINUS_DST_ALPHA 源、目的 (1,1,1,1)-(Ad,Ad,Ad,Ad) GL_SRC_ALPHA_SATURATE 源 (f,f,f,1)-min(As,1-Ad) 还要利用glEnable(GL_BLEND) glDisable(gl_blend)来启用、关闭融合处理。 //////////////////////////////////////////////// //sample.cpp #include <gl/gl.h> #include <gl/glu.h> #include <gl/glaux.h> #pragma comment(lib, "OpenGl32.lib") #pragma comment(lib, "glu32.lib") #pragma comment(lib, "glaux.lib") #pragma warning(disable : 4244) // MIPS #pragma warning(disable : 4136) // X86 #pragma warning(disable : 4051) // ALPHA
void myinit(void); void CALLBACK display(void); void CALLBACK reshape(GLsizei w,GLsizei h); void myinit(void) { auxInitDisplayMode(AUX_SINGLE|AUX_RGBA); auxInitPosition(0,0,500,500); auxInitWindow("sample1"); glClearColor(0.0,0.0,0.0,0.0); glClear(GL_COLOR_BUFFER_BIT); //设置融合效果并启用 glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); // glDepthFunc(GL_LESS); // glEnable(GL_DEPTH_TEST); glShadeModel(GL_FLAT); } void CALLBACK reshape(GLsizei w,GLsizei h) { glViewport(0,0,w,h); glMatrixMode(GL_PROJECTION); glLoadIdentity(); if(w<=h) gluOrtho2D(0.0,1.0,0.0,1.0*(GLfloat)h/(GLfloat)w); else gluOrtho2D(0.0,1.0*(GLfloat)w/(GLfloat)h,0.0,1.0); glMatrixMode(GL_MODELVIEW); } void CALLBACK display(void) { glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); //三个不同颜色和透明度的方块重合,颜色融合的效果 glColor4f(1.0,0.0,0.0,0.7); glRectf(0.25,0.4,0.75,0.9); glColor4f(0.0,1.0,0.0,1.0); glRectf(0.1,0.1,0.6,0.6); glColor4f(0.0,0.0,1.0,0.3); glRectf(0.4,0.1,0.9,0.6); glFlush(); } void main(void) { myinit(); auxReshapeFunc(reshape); auxMainLoop(display); } //end of sample ///////////////////////////////////////////////////////// 你可以试试调节参数大小,体会一下个参数的含义。 2 反走样Anti-aliasing 由于计算机以离散点生成图形,生成图形必然与真实景物存在差距,这种差距 表现为:直线或光滑曲面的锯齿、花纹失去原有色彩形状、细小物体在画面的 消失等。统统叫做走样。反走样可以减少这种情况。粗略设想一下,就是把原 来边界的地方锯齿部分用低饱和度的点补上,这样既不影响整体轮廓,又获得 较好的平滑效果。反走样前提供“提示”采用函数: void glHint(GLenum target,GLenum hint); 其中hint可以是:GL_FASTEST 给出最有效的选择 GL_NICEST 给出最高质量的选择 GL_DONT_CARE 没有选择 target 意义 GL_POINT_SMOOTH_HINT 指定点、 GL_LINE_SMOOTH_HINT 线、 GL_POLYGON_SMOOTH_HINT 多边形的采样质量 GL_FOG_HINT 指出雾化计算是按每个象素进行(GL_NICEST) 还是按每个顶点进行(GL_FASTEST) GL_PERSPECTIVE_CORRECTION_HINT 指定颜色纹理插值的质量 其中GL_PERSPECTIVE_CORRECTION_HINT用以纠正单纯线性插值带来的观察错误。 当然最主要的工作还是glEnable()来完成的。 先给出一个点、线反走样的例子。需要说明的是这个工作最好在RGBA模式下进行, 首先利用glEnable()(参数为GL_POINT_SMOOTH GL_LINE_SMOOTH或 GL_POLYGON_SMOOTH)启用反走样。在RGBA模式下启用反走样,必须启用融合处理。 而且最常用的融合因子分别是:GL_SRC"javascript:if(confirm('http://ins22web.seu.edu.cn/xuray/netschool/support/opengl/_ALPHA(源)和GL_ONE_MINUS_SRC_ALPHA \n\nThis file was not retrieved by Teleport Pro, because it was unavailable, or its retrieval was aborted, or the project was stopped too soon. \n\nDo you want to open it from the server?'))window.location='http://ins22web.seu.edu.cn/xuray/netschool/support/opengl/_ALPHA%A3%A8%D4%B4%A3%A9%BA%CDGL_ONE_MINUS_SRC_A"javascript:if(confirm('http://ins22web.seu.edu.cn/xuray/netschool/support/opengl/LPHA\'" \n\nThis file was not retrieved by Teleport Pro, because it was unavailable, or its retrieval was aborted, or the project was stopped too soon. \n\nDo you want to open it from the server?'))window.location='http://ins22web.seu.edu.cn/xuray/netschool/support/opengl/LPHA%27%22'" tppabs="http://ins22web.seu.edu.cn/xuray/netschool/support/opengl/LPHA%27%22" 或GL_ONE(目的)。 /////////////////////////////////////////////////////////////////////// //sample.cpp #include <gl/gl.h> #include <gl/glu.h> #include <gl/glaux.h> #pragma comment(lib, "OpenGl32.lib") #pragma comment(lib, "glu32.lib") #pragma comment(lib, "glaux.lib") #pragma warning(disable : 4244) // MIPS #pragma warning(disable : 4136) // X86 #pragma warning(disable : 4051) // ALPHA
void myinit(void); void CALLBACK display(void); void CALLBACK reshape(GLsizei w,GLsizei h); void myinit(void) { auxInitDisplayMode(AUX_SINGLE|AUX_RGBA); auxInitPosition(0,0,500,500); auxInitWindow("sample1"); glClearColor(0.0,0.0,0.0,0.0); glClear(GL_COLOR_BUFFER_BIT); //例子所有新内容都在一下4句,你可以试试取消反走样的语句(1、4) //则可以很清楚的比较一下反走样对图象质量的改进。 glEnable(GL_LINE_SMOOTH); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); glHint(GL_LINE_SMOOTH_HINT,GL_DONT_CARE); glDepthFunc(GL_LESS); glEnable(GL_DEPTH_TEST); glShadeModel(GL_FLAT); } void CALLBACK reshape(GLsizei w,GLsizei h) { glViewport(0,0,w,h); glMatrixMode(GL_PROJECTION); glLoadIdentity(); if(w<=h) glOrtho(-5.0,5.0,-5.0*(GLfloat)h/(GLfloat)w, 5.0*(GLfloat)h/(GLfloat)w,-5.0,5.0); else glOrtho(-5.0*(GLfloat)h/(GLfloat)w, 5.0*(GLfloat)h/(GLfloat)w,-5.0,5.0,-5.0,5.0); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); } void CALLBACK display(void) { glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); glLineWidth(5.0); glColor4f(1.0,1.0,0.0,0.7); glPushMatrix(); glRotatef(45.0,1.0,1.0,0.0); auxWireOctahedron(2.0); glPopMatrix(); glFlush(); } void main(void) { myinit(); auxReshapeFunc(reshape); auxMainLoop(display); } //end of sample /////////////////////////////////////////////////////////////////// 再给出一个多边形反走样的例子 /////////////////////////////////////////////////////////////////// //sample.cpp #include <gl/gl.h> #include <gl/glu.h> #include <gl/glaux.h> #pragma comment(lib, "OpenGl32.lib") #pragma comment(lib, "glu32.lib") #pragma comment(lib, "glaux.lib") #pragma warning(disable : 4244) // MIPS #pragma warning(disable : 4136) // X86 #pragma warning(disable : 4051) // ALPHA
void myinit(void); void CALLBACK display(void); void CALLBACK reshape(GLsizei w,GLsizei h); void myinit(void) { auxInitDisplayMode(AUX_SINGLE|AUX_RGBA); auxInitPosition(0,0,500,500); auxInitWindow("sample1"); glClearColor(0.0,0.0,0.0,0.0); glClear(GL_COLOR_BUFFER_BIT); GLfloat mat_ambient[]={0.5,0.5,0.0,1.0}; GLfloat mat_diffuse[]={1.0,0.8,0.1,1.0}; GLfloat position[]={1.0,0.0,1.0,0.0}; glMaterialfv(GL_FRONT,GL_AMBIENT,mat_ambient); glMaterialfv(GL_FRONT,GL_DIFFUSE,mat_diffuse); glLightfv(GL_LIGHT0,GL_POSITION,position); glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); glCullFace(GL_BACK); glEnable(GL_CULL_FACE); //启用多边形反走样 glEnable(GL_POLYGON_SMOOTH); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA,GL_ONE); glDepthFunc(GL_LESS); glEnable(GL_DEPTH_TEST); glShadeModel(GL_FLAT); } void CALLBACK reshape(GLsizei w,GLsizei h) { glViewport(0,0,w,h); glMatrixMode(GL_PROJECTION); glLoadIdentity(); if(w<=h) glOrtho(-5.0,5.0,-5.0*(GLfloat)h/(GLfloat)w, 5.0*(GLfloat)h/(GLfloat)w,-5.0,5.0); else glOrtho(-5.0*(GLfloat)h/(GLfloat)w, 5.0*(GLfloat)h/(GLfloat)w,-5.0,5.0,-5.0,5.0); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); } void CALLBACK display(void) { glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); glLineWidth(5.0); glColor4f(1.0,1.0,0.0,0.7); glPushMatrix(); glRotatef(45.0,1.0,1.0,0.0); auxSolidIcosahedron(2.0); glPopMatrix(); glFlush(); } void main(void) { myinit(); auxReshapeFunc(reshape); auxMainLoop(display); } //end of sample //////////////////////////////////////////////////////////////////// 比较采用反走样后的结果,可以明显看出多变形直线边界出锯齿得到了平滑。 3 雾化 最后来介绍雾化,雾化不但可以使景物更加真实,而且大大减少计算量,开过 F22的玩家不会忘记雾化的远近直接影响游戏的速度吧。一般的雾化模型是考虑 把物体实际颜色和雾化颜色向融合。具体雾化的浓淡有定义的数学模型来决定 包括线性变化、指数变化和指数平方变化等。定义雾化也很简单,只要遵循下面 步骤: 一 启用雾化 glEnable(GL_FOG); 二 控制雾化 glFog*() void glFog{if}[v](GLenum,TYPE param); 当GLenum是GL_FOG MODE时,param可以是GL_EXP(指数) GL_EXP2(指数平方) GL_LINEAR(线性) 当GLenum是GL_FOG_DENSITY GL_FOG_START GL_FOG_END时,param分别指定不同 雾化数学模型下不同计算公式的参量,具体可以参阅连机手册。 当GLenum时GL_FOG_COLOR时,param是指向颜色向量的指针 三 必要时可以用glHint(GL_FOG_HINT,XX)指定雾化效果 下面给出例子: /////////////////////////////////////////////////////////////////// //sample.cpp #include <gl/gl.h> #include <gl/glu.h> #include <gl/glaux.h> #pragma comment(lib, "OpenGl32.lib") #pragma comment(lib, "glu32.lib") #pragma comment(lib, "glaux.lib") #pragma warning(disable : 4244) // MIPS #pragma warning(disable : 4136) // X86 #pragma warning(disable : 4051) // ALPHA
void myinit(void); void CALLBACK display(void); void CALLBACK reshape(GLsizei w,GLsizei h); void myinit(void) { auxInitDisplayMode(AUX_SINGLE|AUX_RGBA); auxInitPosition(0,0,500,500); auxInitWindow("sample1"); glClearColor(0.0,0.0,0.0,0.0); glClear(GL_COLOR_BUFFER_BIT); GLfloat mat_ambient[]={0.0,0.1,0.8,1.0}; GLfloat mat_diffuse[]={0.0,0.3,0.6,1.0}; GLfloat mat_specular[]={1.0,0.0,1.0,1.0}; GLfloat mat_shininess[]={15.0}; GLfloat position[]={5.0,5.0,5.0,0.0}; GLfloat fogColor[4]={0.6,0.6,0.0,1.0}; glMaterialfv(GL_FRONT,GL_AMBIENT,mat_ambient); glMaterialfv(GL_FRONT,GL_DIFFUSE,mat_diffuse); glMaterialfv(GL_FRONT,GL_SPECULAR,mat_specular); glMaterialfv(GL_FRONT,GL_SHININESS,mat_shininess); glLightfv(GL_LIGHT0,GL_POSITION,position); glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); glFrontFace(GL_CW); // glEnable(GL_POLYGON_SMOOTH); // glEnable(GL_BLEND); // glBlendFunc(GL_SRC_ALPHA,GL_ONE); glDepthFunc(GL_LESS); glEnable(GL_DEPTH_TEST); //启用雾化处理 glEnable(GL_FOG); { //采用线性变化的雾化效果 glFogi(GL_FOG_MODE,GL_LINEAR); //指定雾化颜色(黄色) glFogfv(GL_FOG_COLOR,fogColor); //指定按线性变化时计算公式的参量 glFogf(GL_FOG_START,3.0); glFogf(GL_FOG_END,15.0); //规定雾化效果的质量 glHint(GL_FOG_HINT,GL_DONT_CARE); } // glShadeModel(GL_FLAT); } void CALLBACK reshape(GLsizei w,GLsizei h) { glViewport(0,0,w,h); glMatrixMode(GL_PROJECTION); glLoadIdentity(); if(w<=h*3) glOrtho(-6.0,6.0,-2.0*(GLfloat)h*3/(GLfloat)w, 2.0*(GLfloat)h*3/(GLfloat)w,0.0,10.0); else glOrtho(-6.0*(GLfloat)h/(GLfloat)w, 6.0*(GLfloat)h/(GLfloat)w,-2.0,2.0,0.0,10.0); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); } void CALLBACK display(void) { glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); //在不同远近(Z方向)绘制同样大小、颜色的环,显示雾化的效果 glPushMatrix(); glTranslatef(-3.0,-1.5,-3.0); auxSolidTorus(0.6,1.5); glPopMatrix(); glPushMatrix(); glTranslatef(-0.5,-0.5,-6.0); auxSolidTorus(0.6,1.5); glPopMatrix(); glPushMatrix(); glTranslatef(2.0,0.5,-8.0); auxSolidTorus(0.6,1.5); glPopMatrix(); glFlush(); } void main(void) { myinit(); auxReshapeFunc(reshape); auxMainLoop(display); } //end of sample ////////////////////////////////////////////////////////////////////
Tags:  opengl驱动 opengl下载 opengl

延伸阅读

最新评论

发表评论