OpenGL中的颜色再次讨论

一。经过这篇文章后,你将学会如下技能:

1.混合颜色来取得像半透明这样的效果。

2.对于锯齿边缘线和多边形变进行平滑处理。

3.创造真实的大气效果。

二。

1.

如果对OpenGL的透明玻璃效果很好奇,很惊叹,或者很羡慕,或者很想弄.本小节就告诉你背后的真相。从程序的角度来说,叫做混色。从人的角度来说,叫做透明。Blend是Transparent或者Translucent的同义词。

 

下面的变量用于glBlendMode函数。glBlendMode函数主要用于设置混色模式,来取得透明或者半透明效果。

1.当激活“深度测试”的时候,半透明或者透明物体后面的物体仍然不能被“深度测试所剔除”,因此半透明或者透明物体的深度值不能写入到深度缓冲区中。

  但是简单地把透明或者半透明物体关闭深度测试glDisable(GL_DEPTH_TEST),又会使得半透明或者透明物体永远显示在最前面。所以就用了一个折中的办法就是:用glDepthMask函数传入false来保证,既不会关闭深度测试,同时又使得透明或者半透明物体的深度值不写入到深度缓冲区中。这样就保证了,第一。可以被其他物体覆盖。第二。不覆盖其他物体。

这样的技巧很高深。值得推敲。下面是glBlendMode的参数:

Table 7-1 : Source and Destination Blending Factors GL_ZERO source or destination (0, 0, 0, 0) GL_ONE source or destination (1, 1, 1, 1) GL_DST_COLOR source (Rd, Gd, Bd, Ad) GL_SRC_COLOR destination (Rs, Gs, Bs, As) GL_ONE_MINUS_DST_COLOR source (1, 1, 1, 1)-(Rd, Gd, Bd, Ad) GL_ONE_MINUS_SRC_COLOR destination (1, 1, 1, 1)-(Rs, Gs, Bs, As) GL_SRC_ALPHA source or destination (As, As, As, As) GL_ONE_MINUS_SRC_ALPH A source or destination (1, 1, 1, 1)-(As, As, As, As) GL_DST_ALPHA source or destination (Ad, Ad, Ad, Ad) GL_ONE_MINUS_DST_ALPH A source or destination (1, 1, 1, 1)-(Ad, Ad, Ad, Ad) GL_SRC_ALPHA_SATURATE source (f, f, f, 1); f=min(As, 1-Ad)

 

   下面是英文原文,不解释:自己推敲

 

Typically, you want to render both opaque and translucent objects in the same scene, and you want to use the depth buffer to perform hidden-surface removal for objects that lie behind the opaque objects. If an opaque object hides either a translucent object or another opaque object, you want the depth buffer to eliminate the more distant object. If the translucent object is closer, however, you want to blend it with the opaque object. You can generally figure out the correct order to draw the polygons if everything in the scene is stationary, but the problem can easily become too hard if either the viewpoint or the object is moving.

 

The solution is to enable depth-buffering but make the depth buffer read-only while drawing the translucent objects. First you draw all the opaque objects, with the depth buffer in normal operation. Then, you preserve these depth values by making the depth buffer read-only. When the translucent objects are drawn, their depth values are still compared to the values established by the opaque objects, so they aren't drawn if they're behind the opaque ones. If they're closer to the viewpoint, however, they don't eliminate the opaque objects, since the depth-buffer values can't change. Instead, they're blended with the opaque objects. To control whether the depth buffer is writable, use glDepthMask(); if you pass GL_FALSE as the argument, the buffer becomes read-only, whereas GL_TRUE restores the normal, writable operation.

 

 

2.下面是一些系统变量的获取。

     There are four commands for obtaining simple state variables, and one for determining whether a particular state is enabled or disabled.void glGetBooleanv(GLenum pname, GLboolean *params);
void glGetIntegerv(GLenum pname, GLint *params);
void glGetFloatv(GLenum pname, GLfloat *params);
void glGetDoublev(GLenum pname, GLdouble *params);

Obtains Boolean, integer, floating-point, or double-precision state variables. The pname argument is a symbolic constant indicating the state variable to return, and params is a pointer to an array of the indicated type in which to place the returned data. The possible values for pname are listed in the tables in "OpenGL State Variables." A type conversion is performed if necessary to return the desired variable as the requested data type.

GLboolean glIsEnabled(GLenum cap)

Returns GL_TRUE if the mode specified by cap is enabled; otherwise, returns GL_FALSE. The possible values for cap are listed in the tables in "OpenGL State Variables"

Other specialized commands return specific state variables. The prototypes for these commands are listed here; to find out when you need to use these commands, use the tables in "OpenGL State Variables" Also see the OpenGL Reference Manual. OpenGL's error handling facility and the glGetError() command are described in more detail in the next section.

void glGetClipPlane(GLenum plane, GLdouble * equation);
GLenum glGetError(void);
void glGetLight{if} v(GLenum light, GLenum pname, TYPE * params);
void glGetMap{ifd} v(GLenum target, GLenum query, TYPE * v);
void glGetMaterial{if} v(GLenum face, GLenum pname, TYPE * params);
void glGetPixelMap{f ui us} v(GLenum map, TYPE * values);
void glGetPolygonStipple(GLubyte * mask);
const GLubyte * glGetString(GLenum name);
void glGetTexEnv{if} v(GLenum target, GLenum pname, TYPE * params);
void glGetTexGen{ifd} v(GLenum coord, GLenum pname, TYPE * params);
void glGetTexImage(GLenum target, GLint level, GLenum format, GLenum type, GLvoid * pixels);
void glGetTexLevelParameter{if} v(GLenum target, GLint level, GLenum pname, TYPE * params);
void glGetTexParameter{if} v(GLenum target, GLenum pname, TYPE * params); 3.本节介绍的是纹理的颜色如何与像素的颜色进行合并。

最关键的是这个渲染管道:


OpenGL中的颜色再次讨论_第1张图片
 渲染管道也不是什么神秘的东西,最终的目的输入到帧缓冲里面去。而并不关心前面的过程是如何处理的。完全可以由纯软件来实现,也可以用纯硬件,也可以软硬结合。好吧,这是题外话。大部分的计算都是数学运算。

 本节讲不是,TextureAssembly:最后一步是基于片段的操作,则是本节所讲得。

(如果将纹理的颜色应用于片段)

 

1.基于顶点的操作则是进行顶点转换,把顶点转换到一个2*2*2的立方体中。

2.图元装配的任务是裁剪和透视除法。

3.光栅化就是将顶点数据和像素数据(glColor等指定的数据)转换为片段的过程。每个片段对应于帧缓冲中的一个像素。

4.光栅化的同时进行纹理装配。就是给"片段"指定纹理数据。

5.基于片段的操作。各种测试,和颜色混合等运算。

6.纹理装配的含义是进行纹理的拉伸和压缩,平移,打包。并存到系统中。

7.最后一步是基于片段的操作,则是本节所讲得。

(如果将纹理的颜色应用于片段)

 

由上图可以看出,纹理装配和光栅化同时进行。基于片段的操作则是两者结合使用。

下面是纹理颜色的混合策略。glTexEnv来指定。

最关心的是4

4 C = (1

-At)Cf + AtCt, 
A = Af

C = CtCf, 
A = AtAf
undefined

Decal mode makes sense only if the number of components is three or four (remember that texture mapping doesn't work in color-index mode). With three selected components, the color that would have been painted in the absence of any texture mapping (the fragment's color) is replaced by the texture color, and its alpha is unchanged. With four components, the fragment's color is blended with the texture color in a ratio determined by the texture alpha, and the fragment's alpha is unchanged. You use decal mode in situations where you want to apply an opaque texture to an object - if you were drawing a soup can with an opaque label, for example.

 

Table 9-2 : Decal, Modulate, and Blend Functions 1 undefined C = LtCf, 
A = Af C = (1-L

t)Cf + LtCc, 
A = Af

2 undefined C = LtCf, 
A = AtAf C = (1-L

t)Cf + LtCc, 
A = AtAf

3 C = Ct,
A = Af C = CtCf, 
A = Af undefined 4 C = (1

t)Cf + AtCt, 
A = Af

C = CtCf, 
A = AtAf undefined
双缓冲技术:
OpenGL的消隐与双缓冲(2) 博客分类: OpenGL
UP.#include "stdafx.h" 



#include  

#include  

#include  



bool mouseisdown=false ; 

bool loopr=false ; 

int mx,my; 

int ry=30; 

int rx=30; 


 


 

void timer(int p) 

{ 

     ry-=5; 

        glutPostRedisplay(); 

     if (loopr) 

          glutTimerFunc(200,timer,0); 


 


 

} 


 


 

void mouse(int button, int state, int x, int y) 

{ 

    if (button == GLUT_LEFT_BUTTON) 

     { 


 


 

        if (state == GLUT_DOWN) 

         {    mouseisdown=true ; loopr=false ;} 

         else 

              mouseisdown=false ; 

     } 

     if (button== GLUT_RIGHT_BUTTON) 

         if (state == GLUT_DOWN) 

         {loopr=true ; glutTimerFunc(200,timer,0);} 

    

} 


 


 

void motion(int x, int y) 

{ 

    if (mouseisdown==true ) 

    { 

        ry+=x-mx; 

         rx+=y-my; 

         mx=x; 

         my=y; 

         glutPostRedisplay(); 

    } 

} 


 


 

void special(int key, int x, int y) 


 


 

{ 

    switch (key) 

    { 

    case GLUT_KEY_LEFT: 

        ry-=5; 

        glutPostRedisplay(); 

        break ; 

    case GLUT_KEY_RIGHT: 

       ry+=5; 

        glutPostRedisplay(); 

        break ; 

    case GLUT_KEY_UP: 

        rx+=5; 

        glutPostRedisplay(); 

        break ; 

    case GLUT_KEY_DOWN: 

        rx-=5; 

       

        glutPostRedisplay(); 

        break ; 

    } 

} 


 


 


 


 

void init() 

    //设置OpenGL的一些状态变量的初始值 

{ 

    glEnable(GL_DEPTH_TEST);     //深度测试 

    glDepthFunc(GL_LESS);                      //设置深度测试函数 

    glPolygonMode(GL_FRONT_AND_BACK,GL_FILL);        //设置多边形显示模式为正反面都是填充显示 

    glClearColor(1,1,1,1);          //设置刷新背景色 

    glClearDepth(1);          //设置清除深度缓冲区所用的值 

} 


 


 

void display() 

{ 

        

         float red[3]={1,0,0}; 

         float blue[3]={0,1,0}; 

         float green[3]={0,0,1}; 

         float yellow[3]={1,1,0};    


 


 

        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 

         

         

         glLoadIdentity(); 

         glRotatef(ry,0,1,0);       

         glRotatef(rx,1,0,0); 

         

              

         glBegin(GL_QUADS); 

              glColor3fv(green); 

              glVertex3f(0.5,0.5,0); 

              glVertex3f(-0.5,0.5,0); 

              glVertex3f(-0.5,-0.5,0); 

              glVertex3f(0.5,-0.5,0); 

              

         

         glEnd(); 

         

         glBegin(GL_QUADS); 

              glColor3fv(red); 

              glVertex3f(0.5,0.5,0.3); 

              glVertex3f(-0.5,0.5,-0.3); 

              glVertex3f(-0.5,-0.5,-0.3); 

              glVertex3f(0.5,-0.5,0.3); 

              

         

         glEnd(); 

         

         glBegin(GL_QUADS); 

              

              glColor3fv(yellow); 

              glVertex3f(0.5,0.5,-0.3); 

              glVertex3f(-0.5,0.5,0.3); 

              glVertex3f(-0.5,-0.5,0.3); 

              glVertex3f(0.5,-0.5,-0.3); 

              

         

         glEnd(); 


 


 

        glFlush(); 

         glutSwapBuffers(); 



} 

    




int main(int argc, char ** argv) 

{ 

   

    glutInit(&argc, argv); 

    glutInitDisplayMode (GLUT_DOUBLE| GLUT_RGBA|GLUT_DEPTH);         //设置显示模式:单缓冲区, RGBA颜色模式 

    glutInitWindowSize (400, 400);        //设置窗口宽度、高度 

    glutInitWindowPosition(100,100);         //设置窗口位置 

    glutCreateWindow ("double");        //弹出窗口 

     init(); 

    glutDisplayFunc (display);        //设置窗口刷新的回调函数 

     glutMouseFunc(mouse);         //设置鼠标器按键回调函数 

    glutMotionFunc(motion); 

     glutSpecialFunc(special); 

    glutMainLoop();        //开始主循环 

    return 0; 

} 

 

一、所有Activty界面全去掉:

修改AndroidManifest.xml
在application 标签中添加android:theme="@android:style/Theme.NoTitleBar"

 

二、代码方式及对某个Activty有效:

在onCreate中增加:requestWindowFeature(Window.FEATURE_NO_TITLE);

 

void onCreate(Bundle savedInstanceState) {

...

requestWindowFeature(Window.FEATURE_NO_TITLE);

...

}

三、去掉Activity上面的StatusBar

void onCreate(Bundle savedInstanceState) {

...

this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
                WindowManager.LayoutParams.FLAG_FULLSCREEN);

...

}

四、去掉APP 里所有Activity的title bar 和 status bar

修改AndroidManifest.xml
在application 标签中添加

android:theme="@android:style/Theme.NoTitleBar.Fullscreen"

  • OpenGL中的颜色再次讨论_第2张图片
  • 大小: 2.2 KB
  • 查看图片附件

你可能感兴趣的:(OpenGL中的颜色再次讨论)