[Turn] OpenGL Introduction - Lesson 3

The points, lines, and polygons are discussed below.

 

1. About the point

 

The point size defaults to 1 pixel, but it can be changed. The changed command is glPointSize, and its function prototype is as follows:
void glPointSize(GLfloat size);
The size must be greater than 0.0f, the default value is 1.0f, and the unit is "pixel".
Note: For specific OpenGL implementations, there is a limit to the size of the point. If the set size exceeds the maximum value, there may be problems with the setting.
example:

 

void myDisplay(void)
{
    glClear(GL_COLOR_BUFFER_BIT);
    glPointSize(5.0f);
    glBegin(GL_POINTS);
        glVertex2f(0.0f, 0.0f);
        glVertex2f(0.5f, 0.5f);
    glEnd();
    glFlush();
}

 

2. About the line
(1) The width of the line can be specified:
void glLineWidth(GLfloat width);
its usage is similar to glPointSize.
(2) Draw a dotted line.
First, use glEnable(GL_LINE_STIPPLE); to enable dashed line mode (use glDisable(GL_LINE_STIPPLE) to disable it).
Then, use glLineStipple to style the dashed lines.
void glLineStipple(GLint factor, GLushort pattern);
pattern is a sequence of 1 and 0 with a length of 16, starting from the lowest bit, if it is 1, the next factor points on the line that should be drawn will be drawn as real ; if it is 0, the next factor points on the line that should be drawn will be drawn as virtual.
Here are some examples:
http://blog.programfan.com/upfile/200608/20060801172519.gif
Disclaimer: The image is from www.opengl.org, the image is an attached image of the book "OpenGL Programming Guide", since an old edition of the book (first edition, 1994) has been circulated on the Internet, I hope Copyright issues are not touched upon.
Sample code:

 

void myDisplay(void)
{
    glClear(GL_COLOR_BUFFER_BIT);
    glEnable(GL_LINE_STIPPLE);
    glLineStipple(2, 0x0F0F);
    glLineWidth(10.0f);
    glBegin(GL_LINES);
        glVertex2f(0.0f, 0.0f);
        glVertex2f(0.5f, 0.5f);
    glEnd();
    glFlush();
}

 

 

3. About polygons There
are many polygons, and we will talk about the following four aspects.
(1) The two sides of the polygon and how to draw it.
Although we haven't really used 3D coordinates to draw pictures, it is necessary to establish some 3D concepts.
From a three-dimensional perspective, a polygon has two faces. Different drawing methods can be set for each face: fill, only draw edge outlines, only draw vertices, among which "fill" is the default method. You can set different modes for each of the two faces.
glPolygonMode(GL_FRONT, GL_FILL); // Set the front side as filling method
glPolygonMode(GL_BACK, GL_LINE); // Set the back side as edge drawing method
glPolygonMode(GL_FRONT_AND_BACK, GL_POINT); // Set both sides as vertex drawing method

 

 

 

(2) Inversion
The general convention is that "the face whose vertices appear on the screen in counterclockwise order" is the "front", and the other face is the "reverse". The surfaces of common objects in life can usually be represented by such "front" and "reverse", "reasonable" (please find a relatively transparent mineral water bottle, draw a counterclockwise on the side facing you) Circle, and indicate the direction of the drawing, then turn the back to the front, draw a similar circle, and experience the "front" and "reverse". You will find that the direction is facing you, the outside of the bottle is the front, and the back is facing you. The inside of the bottle is the front. The inside facing you and the outside facing away from you are the reverse. In this way, it also belongs to the surface of the "outside of the bottle", but some places are positive, and some places are not. is the opposite).
But there are also some surfaces that are more special. For example "Mobius strip" (Google it yourself), it can be all "front" or all "back".
The concepts of "heads" and "tails" can be swapped with the glFrontFace function.
glFrontFace(GL_CCW); // Set the CCW direction to "Front", CCW is CounterClockWise, counterclockwise
glFrontFace(GL_CW); // Set the CW direction to "Front", CW is ClockWise, clockwise
is a sample program, please use It replaces the myDisplay function in the first lesson, and modifies glFrontFace(GL_CCW) to glFrontFace(GL_CW), and watch the result change.

 

void myDisplay(void)
{
    glClear(GL_COLOR_BUFFER_BIT);
    glPolygonMode(GL_FRONT, GL_FILL); // set front to fill mode
    glPolygonMode(GL_BACK, GL_LINE); // set the back side to line mode
    glFrontFace(GL_CCW); // set the counterclockwise direction to the front
    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();
}

 

 

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

(4)镂空多边形
直线可以被画成虚线,而多边形则可以进行镂空。
首先,使用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   // 这是最上面的一行
};
这样一堆数据非常缺乏直观性,我们需要很费劲的去分析,才会发现它表示的竟然是一只苍蝇。
如果将这样的数据保存成图片,并用专门的工具进行编辑,显然会方便很多。下面介绍如何做到这一点。

 

 

 

首先,用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);


好的,现在请自己编辑一个图片作为mask,并用上述方法取得Mask数组,运行后观察效果。
说明:绘制虚线时可以设置factor因子,但多边形的镂空无法设置factor因子。请用鼠标改变窗口的大小,观察镂空效果的变化情况。

 

#include <stdio.h>
#include <stdlib.h>
void myDisplay(void)
{
    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.5f, -0.5f, 0.0f, 0.0f);  // 在左下方绘制一个有镂空效果的正方形
    glDisable(GL_POLYGON_STIPPLE);
    glRectf(0.0f, 0.0f, 0.5f, 0.5f);    // 在右上方绘制一个无镂空效果的正方形
    glFlush();
}

 

 

 

Summary
This lesson learned some of the details of drawing geometric figures.
Click to set the size.
Lines can have a set width; lines can be drawn as dashed lines.
The drawing method of the two faces of the polygon can be set separately; in three-dimensional space, the invisible polygons can be eliminated; the filled polygons can be drawn in a hollow style.
Knowing these details will make us more handy in some image drawing.
In addition, it is sometimes more convenient to write some data to files outside the program and edit them with special tools.

Reprinted from : http://blog.csdn.net/andyhuabing/article/details/6957224

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=326488455&siteId=291194637