关闭

OpenGL核心概念扫盲--学不懂OpenGL的进

1305人阅读 评论(1) 收藏 举报

http://anony3721.blog.163.com/blog/static/5119742011429341943/


一.帧缓存操作 glClearColor,glClear,glClearDepth

1. glClearColor 设置颜色缓存的清除值

C语言描述

void glClearColor(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha);

参数

redgreenbluealpha 指定清除颜色缓存时所使用的红、绿、蓝和alpha值。

说明

指定由glClear清除颜色缓存时所使用的红、绿、蓝和alpha值,指定值的范围固定为[0.0f1.0f]


2. glClear 将缓存清除为预先的设置值

C语言描述

void glClear(GLbitfield mask);

参数

    mask 对指定的需要清除的缓存进行按位或屏蔽操作,这四个屏蔽值如下:GL_COLOR_BUFFER_BITGL_DEPTH_BUFFER_BITGL_ACCUM_BUFFER_BITGL_STENCIL_BUFFER_BIT

说明

本函数只有一个变量,这个变量对所清除的缓存值进行按位或操作,这些值如下:

GL_COLOR_BUFFER_BIT 指定当前被激活为写操作的颜色缓存。

GL_DEPTH_BUFFER_BIT 指定深度缓存。

GL_ACCUM_BUFFER_BIT 指定累加缓存。

GL_STENCIL_BUFFER_BIT 指定模板缓存。

3. glClearDepth设置深度缓存的清除值

C语言描述

void glClearDepth(GLclampd depth);

参数

   depth 指定清除深度缓存时使用的深度值。

说明

本函数指定用glClear清除深度缓存时所使用的深度值,该值的范围在[01]之间。

二. 颜色使用 glShadeModel,glColor,glColorMask

1. glShadeModel :选择平面明暗模式或光滑明暗模式

C语言描述

void glShadeModel( GLenum mode )

参数

mode 指定表示明暗模式的符号值,可以选择GL_FLAT(平面明暗模式)和GL_SMOOTH(光滑明暗模式),缺省值为GL_SMOOTH。

说明

OpenGL图元需要进行明暗处理,处理得模式可以为平面明暗模式或光滑(Gouraud着色)明暗模式。光滑明暗模式时,多边形各个内部点的颜色是根据各顶点指定的颜色来插值得到的,这意味着两个顶点之间的颜色是从一顶点的颜色渐变到另一顶点的颜色。对于平面明暗模式,整个图元区域的颜色就是最后一个顶点指定的颜色,唯一例外的是GL_POLYGON,这是整个区域的颜色是第一个顶点所指定的颜色。但要注意,如果激活了光照,计算到的顶点颜色都是光照后的结果颜色,若光照关闭,计算到的颜色就是指定顶点时的当前颜色。

2. glColor :设置当前颜色

C语言描述

void glcolor3b(GLbyte red,GLbyte green,GLbyte blue);

void glcolor3d(GLdouble red,GLdouble green,GLdouble blue);

void glcolor3f(GLfloat red,GLfloat green,GLfloat blue);

void glcolor3i(GLint red,GLint green,GLint blue);

void glcolor3s(GLshort red,GLshort green,GLshort blue);

void glcolor3ub(GLubyte red,GLubyte green,GLubyte blue);

void glcolor3ui(GLuint red,GLuint green,GLuint blue);

void glcolor3us(GLushort red,GLushort green,GLushort blue);

void glcolor4b(GLbyte red,GLbyte green,GLbyte blue,GLbyte alpha);

void glcolor4d(GLdouble red,GLdouble green,GLdouble blue,GLdouble alpha);

void glcolor4f(GLfloat red,GLfloat green,GLfloat blue,GLfloat alpha);

void glcolor4i(GLint red,GLint green,GLint blue,GLint alpha);

void glcolor4s(GLshort red,GLshort green,GLshort blue,GLshort alpha);

void glcolor4ub(GLubyte red,GLubyte green,GLubyte blue,GLubyte alpha);

void glcolor4ui(GLuint red,GLuint green,GLuint blue,GLuint alpha);

void glcolor4us(GLushort red,GLushort green,GLushort blue,GLushort alpha);

void glcolor3bv(const GLbyte *v);

void glcolor3dv(const GLdouble *v);

void glcolor3fv(const GLfloat *v);

void glcolor3iv(const GLint *v);

void glcolor3sv(const GLshort *v);

void glcolor3ubv(const GLubyte *v);

void glcolor3uiv(const GLuint *v);

void glcolor3usv(const GLushort *v);

void glcolor4bv(const GLbyte *v);

void glcolor4dv(const GLdouble *v);

void glcolor4fv(const GLfloat *v);

void glcolor4iv(const GLint *v);

void glcolor4sv(const GLshort *v);

void glcolor4ubv(const GLubyte *v);

void glcolor4uiv(const GLuint *v);

void glcolor4usv(const GLushort *v);

参数

red,green, blue 指定当前颜色中的红、绿和蓝色成分。

alpha 指定颜色中的α成分。只有在glColor4函数带4个变量时才指定此参数。

*v 指定一个指向包含红、绿、蓝和alpha值的数组指针。

说明

本函数通过指定红、绿、蓝的颜色成分来设置当前的颜色,同时部分函数可以接受α成分。每个成分亮度的表示范围是从零(0.0)到全光强(1.0),当指定了非浮点类型时,该类型从0到最大值的表示法与浮点类型范围的0.0到1.0相映射。

3. glColorMask :激活或关闭帧缓存颜色分量的写操作

C语言描述

void glColorMask(GLboolean red,GLboolean green,GLboolean blue,GLboolean alpha)

参数

    red,green,blue,alpha 指定红、绿、蓝和α成分是否可以修改。

说明

本函数指定是否可以将单个的颜色分量写入帧缓存。例如,若red为GL_FALSE,那么不管执行什么样的绘制操作,任何颜色缓存中任何像素的红色分量均不被改变。

三. glMatrixMode与glLoadIdentity

glMatrixModeglMatrixMode - 指定哪一个矩阵是当前矩阵 
  C语言描述 
  void glMatrixMode(GLenum mode) 
  参数 
  mode 指定哪一个矩阵堆栈是下一个矩阵操作的目标,可选值: GL_MODELVIEW、GL_PROJECTION、GL_TEXTURE. 
  说明 
  glMatrixMode设置当前矩阵模式: 
  GL_MODELVIEW,对模型视景矩阵堆栈应用随后的矩阵操作. 
  GL_PROJECTION,对投影矩阵应用随后的矩阵操作. 
  GL_TEXTURE,对纹理矩阵堆栈应用随后的矩阵操作. 
  一般总是与glLoadIdentity()一同使用 
glLoadIdentity():该函数的功能是重置当前指定的矩阵为单位矩阵。

四 glCullFace 背面剔除

在三维空间中,一个多边形虽然有两个面,但我们无法看见背面的那些多边形,而一些多边形虽然是正面的,但被其他多边形所遮挡。如果将无法看见的多边形和可见的多边形同等对待,无疑会降低我们处理图形的效率。在这种时候,可以将不必要的面剔除。
首先,使用glEnable(GL_CULL_FACE);来启动剔除功能(使用glDisable(GL_CULL_FACE)可以关闭之)
然后,使用glCullFace来进行剔除。glCullFace的参数可以是GL_FRONT,GL_BACK或者GL_FRONT_AND_BACK,分别表示剔除正面、剔除反面、剔除正反两面的多边形。
注意:剔除功能只影响多边形,而对点和直线无影响。例如,使用glCullFace(GL_FRONT_AND_BACK)后,所有的多边形都将被剔除,所以看见的就只有点和直线。

glCullFace指定要剔出的多边形面 
C语言描述 
   void glCullFace(GLenum mode); 
参数 
   mode  指定应剔除多边形的哪一个面,不是GL_FRONT就是GL_BACK。 
说明 
本函数可以禁用多边形正面或背面上的光照、阴影和颜色计算及操作,消除不必要的渲染计算是因为无论对象如何进行旋转或变换,都不会看到多边形的背面。用GL_CULL_FACE参数调用glEnableglDisable可以启用或禁用剔除。

五 glFrontFace

从三维的角度来看,一个多边形具有两个面。每一个面都可以设置不同的绘制方式:填充、只绘制边缘轮廓线、只绘制顶点,其中“填充”是默认的方式。可以为两个面分别设置不同的方式。
glPolygonMode(GL_FRONT, GL_FILL);            // 设置正面为填充方式
glPolygonMode(GL_BACK, GL_LINE);             // 设置反面为边缘绘制方式
glPolygonMode(GL_FRONT_AND_BACK, GL_POINT); // 设置两面均为顶点绘制方式
一般约定为“顶点以逆时针顺序出现在屏幕上的面”为“正面”,另一个面即成为“反面”。生活中常见的物体表面,通常都可以用这样的“正面”和“反面”,“合理的”被表现出来(请找一个比较透明的矿泉水瓶子,在正对你的一面沿逆时针画一个圆,并标明画的方向,然后将背面转为正面,画一个类似的圆,体会一下“正面”和“反面”。你会发现正对你的方向,瓶的外侧是正面,而背对你的方向,瓶的内侧才是正面。正对你的内侧和背对你的外侧则是反面。这样一来,同样属于“瓶的外侧”这个表面,但某些地方算是正面,某些地方却算是反面了)。
但也有一些表面比较特殊。例如“麦比乌斯带”(请自己Google一下),可以全部使用“正面”或全部使用“背面”来表示。
可以通过glFrontFace函数来交换“正面”和“反面”的概念。
glFrontFace(GL_CCW);   // 设置CCW方向为“正面”,CCW即CounterClockWise,逆时针
glFrontFace(GL_CW);    // 设置CW方向为“正面”,CW即ClockWise,顺时针

下面是一个示例程序,请将glFrontFace(GL_CCW)修改为glFrontFace(GL_CW),并观察结果的变化。
#include "windows.h"
#include <GL/gl.h> 
#include <GL/glu.h> 
#include <GL/glaux.h> 
void myinit(void); 
void draw_triangle(void); 
void CALLBACK display(void); 
void CALLBACK myReshape(GLsizei w, GLsizei h); 
void draw_triangle(void) 

 glBegin(GL_LINE_LOOP); 
 glVertex2f(0.0, 25.0); 
 glVertex2f(25.0, -25.0); 
 glVertex2f(-25.0, -25.0); 
 glEnd(); 

void CALLBACK display(void) 

 glClear(GL_COLOR_BUFFER_BIT);
 glPolygonMode(GL_FRONT, GL_FILL); // 设置正面为填充模式
 glPolygonMode(GL_BACK, GL_LINE);   // 设置反面为线形模式
 glFrontFace(GL_CCW);  // 设置逆时针方向为正面;请将glFrontFace(GL_CCW)修改为glFrontFace(GL_CW),对比结果
 glBegin(GL_POLYGON);               // 按逆时针绘制一个正方形,在左下方
 glVertex2f(-0.5f, -0.5f);
 glVertex2f(0.0f, -0.5f);
 glVertex2f(0.0f, 0.0f);
 glVertex2f(-0.5f, 0.0f);
 glEnd();
 glBegin(GL_POLYGON);               // 按顺时针绘制一个正方形,在右上方
 glVertex2f(0.0f, 0.0f);
 glVertex2f(0.0f, 0.5f);
 glVertex2f(0.5f, 0.5f);
 glVertex2f(0.5f, 0.0f);
 glEnd();
 glFlush();


void myinit (void) 

 glClearColor (0.0, 0.0, 0.0, 1.0);
 glShadeModel (GL_FLAT); 

void CALLBACK myReshape(GLsizei w, GLsizei h) 

 glViewport(0, 0, w, h); 
 glMatrixMode(GL_PROJECTION); 
 glLoadIdentity(); 
 if (w <= h) 
  glOrtho(-1.0, 1.0, -1.0*(GLfloat)h/(GLfloat)w, 1.0*(GLfloat)h/(GLfloat)w,-1.0,1.0);  //平行投影
 else 
  glOrtho(-1.0*(GLfloat)w/(GLfloat)h, 1.0*(GLfloat)w/(GLfloat)h, -1.0, 1.0,-1.0,1.0); 
 glMatrixMode(GL_MODELVIEW); 

void main(void) 

 auxInitDisplayMode (AUX_SINGLE | AUX_RGBA); 
 auxInitPosition (0, 0, 500, 500); 
 auxInitWindow ("Geometric Transformations"); 
 myinit (); 
 auxReshapeFunc (myReshape); 
 auxMainLoop(display);  //在这里进行绘制
}
六 glBegin和glEnd

在glBegin和glEnd之间,只能放与点直接相关的函数,例如:指定顶点、指定顶点颜色、指定顶点材质……,总之是与顶点直接有关的与点没有直接联系的glEnable,glLineWidth等,在glBegin和glEnd之间出现将被忽略。

查了资料,在glBegin和glEnd之间,只有以下函数是有效的,其它函数全部会被忽略。
glVertex*
glColor*
glIndex*
glSecondaryColor*
glNormal*
glMaterial*
glFogCood*
glTexCood*
glMultiTexCood*
glEdgeFlag*
glArrayElement*
glEvalCoord*
glEvalPoint*
glCallList
glCallLists



http://zhgw01.blog.163.com/blog/static/10414812201051935944323/

opengl里面的深度缓存


在现实生活中,一个实心物体挡在另外一个实心物体的前面, 后面的那个物体有部分会被遮盖掉

那么opengl里面如何模拟这个情况呢? 每个物体的每个像素都有一个深度缓存的值(在0到1之间,可以想象成是z轴的距离)

如果glDepthFunc启用了GL_LESS(现实生活中的前景), 那么当前个物体挡住后个物体时, 由于前个物体深度值小(越靠近人的), 所以它就被画了出来, 后面的物体被挡住的像素就被忽略掉了。(当然你如果启用了GL_GREATER, 那么情况就反过来了)

这个时候再来说glClearDepth, 它给深度缓冲指定了一个初始值,缓冲中的每个像素的深度值都是这个, 比如1,这个时候你往里面画一个物体, 由于物体的每个像素的深度值都小于等于1, 所以整个物体都被显示了出来。 如果初始值指定为0, 物体的每个像素的深度值都大于等于0, 所以整个物体都不可见。 如果初始值指定为0.5, 那么物体就只有深度小于0.5的那部分才是可见的

0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:235026次
    • 积分:3694
    • 等级:
    • 排名:第8746名
    • 原创:119篇
    • 转载:62篇
    • 译文:7篇
    • 评论:27条
    订阅博客
    博客专栏
    最新评论