第4课:OpenGL几何图原——多边形

 看下面一个关于多边形的程序:     

#include < windows.h >       
#include 
< GL / glut.h >       

void  myDisplay( void )      
{      
    glClear(GL_COLOR_BUFFER_BIT);      
    glPolygonMode(GL_FRONT, GL_FILL); 
//  设置正面为填充模式      
    glPolygonMode(GL_BACK, GL_LINE);   //  设置反面为线形模式      
    glFrontFace(GL_CCW);               //  设置逆时针方向为正面      
    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();      
}      

int  main( int  argc,  char   * argv[])      
{      
    glutInit(
& argc, argv);      
    glutInitDisplayMode(GLUT_RGB 
|  GLUT_SINGLE);      
    glutInitWindowPosition(
100 100 );      
    glutInitWindowSize(
400 400 );      
    glutCreateWindow(
" 画多边形(正面为填充模式,反面为线形模式) " );      
    glutDisplayFunc(
& myDisplay);      
    glutMainLoop();      
    
return   0 ;      
}      
运行效果图如下:    
 
第4课:OpenGL几何图原——多边形_第1张图片
填充模式有如下几种:     
          填充模式                                   解释说明     
glPolygonMode(GL_FRONT, GL_FILL);                                       设置正面为填充方式     
glPolygonMode(GL_BACK, GL_LINE);                                         设置反面为边缘绘制方式     
glPolygonMode(GL_FRONT_AND_BACK, GL_POINT);           设置两面均为顶点绘制方式     

例如, 我们将程序中如下句     
glPolygonMode(GL_FRONT, GL_FILL); // 设置正面为填充模式     
glPolygonMode(GL_BACK, GL_LINE);  // 设置反面为线形模式     
改为     
glPolygonMode(GL_FRONT_AND_BACK, GL_POINT); // 设置两面均为顶点绘制方式     
glPolygonMode(GL_FRONT_AND_BACK, GL_POINT); // 设置两面均为顶点绘制方式     

效果图如下:
      
第4课:OpenGL几何图原——多边形_第2张图片
可以通过glFrontFace函数来交换“正面”和“反面”的概念,如下:     

glFrontFace(GL_CCW);  // 设置CCW方向为“正面”,CCW即CounterClockWise,逆时针     
glFrontFace(GL_CW);   // 设置CW方向为“正面”,CW即ClockWise,顺时针     

若将程序中glFrontFace(GL_CCW);换成glFrontFace(GL_CW);则效果图如下:  
第4课:OpenGL几何图原——多边形_第3张图片
下面我想借用网络上的例子来说明一下自己的心得,其中部分文字来自网络。 

剔除多边形表面 

在三维空间中,一个多边形虽然有两个面,但我们无法看见背面的那些多边形,而一些多边形虽然是正面的,但被其他多边形所遮挡。如果将无法看见的多边形和可见的多边形同等对待,无疑会降低我们处理图形的效率。在这种时候,可以将不必要的面剔除。 

使用glEnable(GL_CULL_FACE);来启动剔除功能(使用glDisable(GL_CULL_FACE)可以关闭之) 

使用glCullFace来进行剔除。 

glCullFace的参数可以是GL_FRONT,GL_BACK或者GL_FRONT_AND_BACK,分别表示剔除正面、剔除反面、剔除正反两面的多边形。 

注意:剔除功能只影响多边形,而对点和直线无影响。例如,使用glCullFace(GL_FRONT_AND_BACK)后,所有的多边形都将被剔除,所以看见的就只有点和直线。 

镂空多边形 

这个可是很好玩的啊~~ 

直线可以被画成虚线,而多边形则可以进行镂空。 

首先,使用glEnable(GL_POLYGON_STIPPLE);来启动镂空模式(使用glDisable(GL_POLYGON_STIPPLE)可以关闭之)。 

然后,使用glPolygonStipple来设置镂空的样式。 
void glPolygonStipple(const GLubyte *mask); 
其中的参数mask指向一个长度为128字节的空间,它表示了一个32*32的矩形应该如何镂空。其中:第一个字节表示了最左下方的从左到右(也可以是从右到左,这个可以修改)8个像素是否镂空(1表示不镂空,显示该像素;0表示镂空,显示其后面的颜色),最后一个字节表示了最右上方的8个像素是否镂空。 

但是,如果我们直接定义这个mask数组,像这样: 
static  GLubyte Mask[ 128 =   
{  
    
0x00 0x00 0x00 0x00 ,    //   这是最下面的一行  
     0x00 0x00 0x00 0x00 ,  
    
0x03 0x80 0x01 0xC0 ,    //   麻  
     0x06 0xC0 0x03 0x60 ,    //   烦  
     0x04 0x60 0x06 0x20 ,    //   的  
     0x04 0x30 0x0C 0x20 ,    //   初  
     0x04 0x18 0x18 0x20 ,    //   始  
     0x04 0x0C 0x30 0x20 ,    //   化  
     0x04 0x06 0x60 0x20 ,    //   ,  
     0x44 0x03 0xC0 0x22 ,    //   不  
     0x44 0x01 0x80 0x22 ,    //   建  
     0x44 0x01 0x80 0x22 ,    //   议  
     0x44 0x01 0x80 0x22 ,    //   使  
     0x44 0x01 0x80 0x22 ,    //   用  
     0x44 0x01 0x80 0x22 ,  
    
0x44 0x01 0x80 0x22 ,  
    
0x66 0x01 0x80 0x66 ,  
    
0x33 0x01 0x80 0xCC ,  
    
0x19 0x81 0x81 0x98 ,  
    
0x0C 0xC1 0x83 0x30 ,  
    
0x07 0xE1 0x87 0xE0 ,  
    
0x03 0x3F 0xFC 0xC0 ,  
    
0x03 0x31 0x8C 0xC0 ,  
    
0x03 0x3F 0xFC 0xC0 ,  
    
0x06 0x64 0x26 0x60 ,  
    
0x0C 0xCC 0x33 0x30 ,  
    
0x18 0xCC 0x33 0x18 ,  
    
0x10 0xC4 0x23 0x08 ,  
    
0x10 0x63 0xC6 0x08 ,  
    
0x10 0x30 0x0C 0x08 ,  
    
0x10 0x18 0x18 0x08 ,  
    
0x10 0x00 0x00 0x08     //  这是最上面的一行  
};  

这样一堆数据非常缺乏直观性,我们需要很费劲的去分析,才会发现它表示的竟然是一只苍蝇。 

我们看一看源程序及其运行效果图吧 : 

#include < windows.h >   
#include 
< GL / glut.h >   
void  myDisplay( void )  
{  
    
static  GLubyte Mask[ 128 =   
{  
    
0x00 0x00 0x00 0x00 ,    //   这是最下面的一行  
     0x00 0x00 0x00 0x00 ,  
    
0x03 0x80 0x01 0xC0 ,    //   麻  
     0x06 0xC0 0x03 0x60 ,    //   烦  
     0x04 0x60 0x06 0x20 ,    //   的  
     0x04 0x30 0x0C 0x20 ,    //   初  
     0x04 0x18 0x18 0x20 ,    //   始  
     0x04 0x0C 0x30 0x20 ,    //   化  
     0x04 0x06 0x60 0x20 ,    //   ,  
     0x44 0x03 0xC0 0x22 ,    //   不  
     0x44 0x01 0x80 0x22 ,    //   建  
     0x44 0x01 0x80 0x22 ,    //   议  
     0x44 0x01 0x80 0x22 ,    //   使  
     0x44 0x01 0x80 0x22 ,    //   用  
     0x44 0x01 0x80 0x22 ,  
    
0x44 0x01 0x80 0x22 ,  
    
0x66 0x01 0x80 0x66 ,  
    
0x33 0x01 0x80 0xCC ,  
    
0x19 0x81 0x81 0x98 ,  
    
0x0C 0xC1 0x83 0x30 ,  
    
0x07 0xE1 0x87 0xE0 ,  
    
0x03 0x3F 0xFC 0xC0 ,  
    
0x03 0x31 0x8C 0xC0 ,  
    
0x03 0x3F 0xFC 0xC0 ,  
    
0x06 0x64 0x26 0x60 ,  
    
0x0C 0xCC 0x33 0x30 ,  
    
0x18 0xCC 0x33 0x18 ,  
    
0x10 0xC4 0x23 0x08 ,  
    
0x10 0x63 0xC6 0x08 ,  
    
0x10 0x30 0x0C 0x08 ,  
    
0x10 0x18 0x18 0x08 ,  
    
0x10 0x00 0x00 0x08     //  这是最上面的一行  
};  
glClear(GL_COLOR_BUFFER_BIT);  
glEnable(GL_POLYGON_STIPPLE);  
    glPolygonStipple(Mask);  
    glRectf(
- 0.5f - 0.5f 0.0f 0.0f );   //  在左下方绘制一个有镂空效果的正方形  
    glDisable(GL_POLYGON_STIPPLE);  
    glRectf(
0.0f 0.0f 0.5f 0.5f );     //  在右上方绘制一个无镂空效果的正方形  
    glFlush();  

}  

int  main( int  argc,  char   * argv[])  
{  
    glutInit(
& argc, argv);  
    glutInitDisplayMode(GLUT_RGB 
|  GLUT_SINGLE);  
    glutInitWindowPosition(
100 100 );  
    glutInitWindowSize(
400 400 );  
    glutCreateWindow(
" 画多边形(镂空) " );  
    glutDisplayFunc(
& myDisplay);  
    glutMainLoop();  
    
return   0 ;  
}  

效果图是这样的: 
 
第4课:OpenGL几何图原——多边形_第4张图片
首先,用Windows自带的画笔程序新建一副图片,取名为mask.bmp,注意保存时,应该选择“单色位图”。在“图象”->“属性”对话框中,设置图片的高度和宽度均为32。 
用放大镜观察图片,并编辑之。黑色对应二进制零(镂空),白色对应二进制一(不镂空),编辑完毕后保存。 
然后,就可以使用以下代码来获得这个Mask数组了。 

static  GLubyte Mask[ 128 ];  
FILE 
* fp;  
fp 
=  fopen( " mask.bmp " " rb " );  
if ! fp )  
    exit(
0 );  
//  移动文件指针到这个位置,使得再读sizeof(Mask)个字节就会遇到文件结束  
//  注意-(int)sizeof(Mask)虽然不是什么好的写法,但这里它确实是正确有效的  
//  如果直接写-sizeof(Mask)的话,因为sizeof取得的是一个无符号数,取负号会有问题  
if ( fseek(fp,  - ( int ) sizeof (Mask), SEEK_END) )  
    exit(
0 );  
//  读取sizeof(Mask)个字节到Mask  
if ! fread(Mask,  sizeof (Mask),  1 , fp) )  
    exit(
0 );  
fclose(fp);  

[注意] 关于文件操作,可以查阅C语言程序设计相关图书。 

这里我在Mask.bmp上写了一个“易”字。 

看如下经过改进后的程序及其运行结果: 

#include < windows.h >   
#include 
< GL / glut.h >   
#include 
< stdio.h >   
#include 
< stdlib.h >   
void  myDisplay( void )  
{  
    
static  GLubyte Mask[ 128 ];  
    FILE 
* fp;  
    fp 
=  fopen( " D:/abc/Mask.bmp " " rb " );  
    
if ! fp )  
        exit(
0 );  
    
if ( fseek(fp,  - ( int ) sizeof (Mask), SEEK_END) )  
        exit(
0 );  
    
if ! fread(Mask,  sizeof (Mask),  1 , fp) )  
        exit(
0 );  
    fclose(fp);  
    glClear(GL_COLOR_BUFFER_BIT);  
    glEnable(GL_POLYGON_STIPPLE);  
    glPolygonStipple(Mask);  
    glRectf(
- 0.5f - 0.5f 0.0f 0.0f );   //  在左下方绘制一个有镂空效果的正方形  
    glDisable(GL_POLYGON_STIPPLE);  
    glRectf(
0.0f 0.0f 0.5f 0.5f );     //  在右上方绘制一个无镂空效果的正方形  
    glFlush();  
}  

int  main( int  argc,  char   * argv[])  
{  
    glutInit(
& argc, argv);  
    glutInitDisplayMode(GLUT_RGB 
|  GLUT_SINGLE);  
    glutInitWindowPosition(
100 100 );  
    glutInitWindowSize(
400 400 );  
    glutCreateWindow(
" 画多边形(镂空) " );  
    glutDisplayFunc(
& myDisplay);  
    glutMainLoop();  
    
return   0 ;  
}  

运行效果如下: 
第4课:OpenGL几何图原——多边形_第5张图片
[注意] 

我的运行环境是VC++ 6.0。 

我在第一次运行时,这一句fp = fopen("D://abc//Mask.bmp", "rb");我用的是相对路径 fp = fopen("Mask.bmp", "rb");结果没有成功,但是在Micosoft Studio 2005中用相对路径应该可以实现的,所以绝对路径是一种选择。

你可能感兴趣的:(图形编程,fp,buffer,vc++,c,file,网络)