opengl 多边形线框_OpenGl(二)点线设置、多边形镂空

这篇博客介绍了如何使用OpenGL调整图形样式,包括设置点的大小、线的宽度和虚线模式,以及多边形的正面与反面显示、剔除反面和镂空效果。通过示例代码详细展示了每种设置的方法及其视觉效果。
摘要由CSDN通过智能技术生成

1. 改变点的大小

OpenGL中默认点的大小是1个像素,使用函数glPointSIze可以调整点的大小,入参是GLfloat,相当于是浮点数。

相关代码:

void myDisplay(void)

{

//设置点的大小

glClear(GL_COLOR_BUFFER_BIT);

glPointSize(5); //设置点的大小为5个像素

glColor4f(0,0,1,0); //设置颜色为蓝色

glBegin(GL_POINTS); //绘制点

glVertex2f(0,0);

glVertex2f(0.6,0.6);

glEnd();

glFlush();

}

效果:

2. 改变直线的宽度

线宽的设置用函数glLineWidth,入参是GLfloat,必须大于0.0f。

相关代码:

void myDisplay(void)

{

//设置线的宽度

glClear(GL_COLOR_BUFFER_BIT);

glLineWidth(5);

glBegin(GL_LINES);

glVertex2f(-0.5,-0.5);

glVertex2f(0.5,-0.5);

glEnd();

glFlush();

}

效果:

3. 设置直线显示模式为虚线

对虚线的设置需要先用函数glEnable(GL_LINE_STIPPLE)开启虚线模式,之后使用glLineStipple函数设置,它有连个参数。

void  glLineStipple (GLint factor, GLushort pattern);

第一个参数是直线上一个片段的像素个数,第二个参数是一个由1和0组成的16位序列,从最低位开始,如果为1,则线段上从起点开始的factor个像素点被绘制为实的,如果为0,则会被绘制成虚的。其对应关系如下图所示:

相关代码:

void myDisplay(void)

{

//设置虚线模式

glClear(GL_COLOR_BUFFER_BIT);

glLineWidth(3);

glEnable(GL_LINE_STIPPLE);

glLineStipple(0,0X00FF);

glBegin(GL_LINES);

glVertex2f(-0.8,0.5);

glVertex2f(0.8,0.5);

glEnd();

glFlush();

}

显示效果:

4. 多边形

4.1 多边形的正面和反面

三维空间中的一个平面多边形(即厚度为0的多边形)具有两个面,就像一张纸具有正面和反面一样。在OpenGL中可以对正反面分别设置不同的填充、边缘线轮廓填充方式等。

一般约定,“顶点以逆时针顺序呈现在窗口上的面”为正面,以顺时针顺序呈现的面为反面。

下边绘制一个正面多边形和一个反面多边形,相关代码:

void myDisplay(void)

{

//正反面分别设置不同的模式、正反面调换

glClear(GL_COLOR_BUFFER_BIT);

glPolygonMode(GL_FRONT,GL_FILL); //设置正面为填充模式

glPolygonMode(GL_BACK,GL_LINE); //设置反面为线形模式

//glPolygonMode(GL_FRONT_AND_BACK,GL_POINT); //正反面都设置为顶点绘制方式

glFrontFace(GL_CCW); //设置逆时针为正面,为系统默认

//glFrontFace(GL_CW); //设置顺时针为正面

glBegin(GL_POLYGON);

glVertex2f(0,0);

glVertex2f(-0.5,0);

glVertex2f(-0.5,-0.5);

glVertex2f(0,-0.5);

glEnd();

glBegin(GL_POLYGON);

glVertex2f(0,0.5);

glVertex2f(0.5,0.5);

glVertex2f(0.5,0);

glVertex2f(0,0);

glEnd();

glFlush();

}

效果:

正反面可以通过函数glFrongFace来交换,正面被设置为反面的同时,反面被自动设置为正面,效果:

4.2 剔除多边形的反面

空间三维中的一个多边形(注意是多边形,不是三维物体)在二维平面显示的时候,多边形的反面是被遮挡看不见的,或者是一个多边形被另一个多边形遮挡住的情况,如果把这种情况跟正面显示的部分同等对待处理的话,会降低处理图形的效率,因为就算花费了大量时间去处理,在最终的显示上也是体现不出来的,相当于是做了无用功。所以需要把这些面剔除掉,在处理的时候不参与运算。

使用glEnable(GL_CULL_FACE)来激活剔除功能,使用glCullFace来剔除指定的反面(或正面)。

相关代码:

void myDisplay(void)

{

//剔除正面示例

glClear(GL_COLOR_BUFFER_BIT);

glPolygonMode(GL_FRONT_AND_BACK,GL_FILL);

glEnable(GL_CULL_FACE);

glCullFace(GL_FRONT);

glBegin(GL_POLYGON);

glVertex2f(0,0);

glVertex2f(-0.5,0);

glVertex2f(-0.5,-0.5);

glVertex2f(0,-0.5);

glEnd();

glBegin(GL_POLYGON);

glVertex2f(0,0);

glVertex2f(0,0.5);

glVertex2f(0.5,0.5);

glVertex2f(0.5,0);

glEnd();

glFlush();

glBegin(GL_POLYGON);

glVertex2f(0,0.5);

glVertex2f(0.5,0.5);

glVertex2f(0.5,0);

glVertex2f(0,0);

glEnd();

glFlush();

}

本例指定剔除正面,剔除前:                                               剔除后:

           

4.3 多边形的镂空

多边形可以设置镂空效果,使用glEnable(GL_POLYGON_STIPPLE)开启镂空模式,之后使用glPolygonStipple

设置镂空基本图案。

void   glPolygonStipple (const GLubyte *mask);

mask是一个指向32*32*8bit的矩形空间,这个矩形空间中前8位表示图案最下方从左到右的8位像素的显示方式,1不镂空,0镂空显示背景色。

可以用一幅大小为32*32像素的图案来定义多边形镂空的基本样式单元。

制作方式为:

1. 打开Windows自带的画图程序,新建一个空白图像2. 按下Ctrl+E,打开属性页,设置宽度和高度都为32

3. 按下Ctrl键,之后波动鼠标滚轮放大图像到最大,在图像标题栏“查看”项里勾选标尺和网格线,方便作图:

4. 之后就可以用画笔在上边做你想要镂空的图案了,做完之后另存为mask.bmp,并且保存类型里选择“单色位图”,忽略警告。

相关代码:

void myDisplay(void)

{

//镂空效果

glClear(GL_COLOR_BUFFER_BIT);

static GLubyte Mask[128];

FILE *fp;

fp = fopen("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.7f, -0.7f, 0.7f, 0.7f); // 绘制一个有镂空效果的正方形

glFlush();

}

效果:

完整代码:

#include

#include

using namespace std;

void myDisplay(void)

{

//设置点的大小

glClear(GL_COLOR_BUFFER_BIT);

glPointSize(5); //设置点的大小为5个像素

glBegin(GL_POINTS); //绘制点

glVertex2f(0,0);

glVertex2f(0.6,0.6);

glEnd();

glFlush();

system("pause");

//设置线的宽度

glLineWidth(5);

glBegin(GL_LINES);

glVertex2f(-0.4,-0.4);

glVertex2f(0.4,-0.4);

glEnd();

glFlush();

system("pause");

//设置虚线模式

glLineWidth(3);

glEnable(GL_LINE_STIPPLE);

glLineStipple(0,0X00FF);

glBegin(GL_LINES);

glVertex2f(-0.8,0.8);

glVertex2f(0.8,0.8);

glEnd();

glFlush();

system("pause");

//正反面分别设置不同的模式、正反面调换

glPolygonMode(GL_FRONT,GL_FILL); //设置正面为填充模式

glPolygonMode(GL_BACK,GL_LINE); //设置反面为线形模式

//glPolygonMode(GL_FRONT_AND_BACK,GL_POINT); //正反面都设置为顶点绘制方式

glFrontFace(GL_CCW); //设置逆时针为正面,为系统默认

//glFrontFace(GL_CW); //设置顺时针为正面

glBegin(GL_POLYGON);

glVertex2f(0,0);

glVertex2f(-0.5,0);

glVertex2f(-0.5,-0.5);

glVertex2f(0,-0.5);

glEnd();

glBegin(GL_POLYGON);

glVertex2f(0,0.5);

glVertex2f(0.5,0.5);

glVertex2f(0.5,0);

glVertex2f(0,0);

glEnd();

glFlush();

system("pause");

//剔除正面示例

glClear(GL_COLOR_BUFFER_BIT);

glPolygonMode(GL_FRONT_AND_BACK,GL_FILL);

glEnable(GL_CULL_FACE);

glCullFace(GL_FRONT);

glBegin(GL_POLYGON);

glVertex2f(0,0);

glVertex2f(-0.5,0);

glVertex2f(-0.5,-0.5);

glVertex2f(0,-0.5);

glEnd();

glBegin(GL_POLYGON);

glVertex2f(0,0);

glVertex2f(0,0.5);

glVertex2f(0.5,0.5);

glVertex2f(0.5,0);

glEnd();

glFlush();

glBegin(GL_POLYGON);

glVertex2f(0,0.5);

glVertex2f(0.5,0.5);

glVertex2f(0.5,0);

glVertex2f(0,0);

glEnd();

glFlush();

system("pause");

//镂空效果

glClear(GL_COLOR_BUFFER_BIT);

glDisable(GL_CULL_FACE);

static GLubyte Mask[128];

FILE *fp;

fp = fopen("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.7f, -0.7f, 0.7f, 0.7f); // 绘制一个有镂空效果的正方形

glFlush();

}

int main(int argc, char *argv[])

{

glutInit(&argc, argv); //初始化GLUT

glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE);

glutInitWindowPosition(500, 200);

glutInitWindowSize(400, 400);

glutCreateWindow("OpenGL");

glutDisplayFunc(&myDisplay); //回调函数

glutMainLoop(); //持续显示,当窗口改变会重新绘制图形

return 0;

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值