OpenGL study notes: drawing points, lines and polygons (second lecture)

1. The size of the 
dots
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 myDisplay1(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 straight 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);
The 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 line will be drawn The next factor points that should be drawn will be drawn as virtual. 

Here are some examples:


Disclaimer: The picture is from www.opengl.org, which is a picture of the book "OpenGL Programming Guide". Since the old version of the book (first edition, 1994) has been circulated on the Internet, I hope that the copyright issue has not been touched .

Sample code:

void myDisplay2(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(1.0f, 1.0f);
    glEnd();
    glFlush();
}
3. There 
is more content about polygons. 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 front as fill mode
glPolygonMode(GL_BACK, GL_LINE); // Set the back side as the edge drawing method
glPolygonMode(GL_FRONT_AND_BACK, GL_POINT); // Set both sides to be vertex drawing
(2) The general convention for inversion 
is that "the face whose vertices appear on the screen in counter-clockwise order" is the "front face", and the other face becomes the "reverse face".
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

The following is a sample program, please use it to replace the myDisplay function in the first lesson, modify glFrontFace(GL_CCW) to glFrontFace(GL_CW), and observe the change of the result.

void myDisplay3(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); // Draw a square counterclockwise, at the bottom left
    glVertex2f(-0.5f, -0.5f);
    glVertex2f(0.0f, -0.5f);
    glVertex2f(0.0f, 0.0f);
    glVertex2f(-0.5f, 0.0f);
    glEnd();
    glBegin(GL_POLYGON); // draw a square clockwise, top right
    glVertex2f(0.0f, 0.0f);
    glVertex2f(0.0f, 0.5f);
    glVertex2f(0.5f, 0.5f);
    glVertex2f(0.5f, 0.0f);
    glEnd();
    glFlush();
}
(3) Removing polygon surfaces 
In three-dimensional space, although a polygon has two faces, we cannot see those polygons on the back, and some polygons are front faces, but they are occluded by other polygons. If we treat invisible polygons and visible polygons the same, it will undoubtedly reduce the efficiency of our graphics processing. At such times, unnecessary faces can be culled. 
First, use glEnable(GL_CULL_FACE); to enable culling (use glDisable(GL_CULL_FACE) to disable it) 
and then use glCullFace to cull. 
The parameters of glCullFace can be GL_FRONT, GL_BACK or GL_FRONT_AND_BACK, which means to cull front, back, and front and back polygons respectively. 
Note: The culling function only affects polygons, not points and lines. For example, with glCullFace(GL_FRONT_AND_BACK), all polygons will be culled, so only points and lines are visible.
(4) Hollow polygon 
straight lines can be drawn as dotted lines, while polygons can be hollowed out. 
First, use glEnable(GL_POLYGON_STIPPLE); to enable hollow mode (use glDisable(GL_POLYGON_STIPPLE) to disable it). 

Then, use glPolygonStipple to style the hollow. 

void glPolygonStipple(const GLubyte *mask);
The parameter mask points to a space with a length of 128 bytes, which indicates how a 32*32 rectangle should be hollowed out.
Among them: the first byte indicates whether the bottom leftmost 8 pixels from left to right (or from right to left, this can be modified) are hollowed out (1 means not hollowed out, display the pixel; 0 means hollowed out, display The color behind it), the last byte indicates whether the upper-right 8 pixels are hollowed out. 

However, if we define this mask array directly, like this:

static GLubyte Mask[128] =
{ 0x00, 0x00, 0x00, 0x00, // this is the bottom line
  0x00, 0x00, 0x00, 0x00,
  0x03, 0x80, 0x01, 0xC0, // hemp
  0x06, 0xC0, 0x03, 0x60, // annoying
  0x04, 0x60, 0x06, 0x20, // of
  0x04, 0x30, 0x0C, 0x20, // Initial
  0x04, 0x18, 0x18, 0x20, // start
  0x04, 0x0C, 0x30, 0x20, // convert
  0x04, 0x06, 0x60, 0x20, // ,
  0x44, 0x03, 0xC0, 0x22, // no
  0x44, 0x01, 0x80, 0x22, // build
  0x44, 0x01, 0x80, 0x22, // negotiable
  0x44, 0x01, 0x80, 0x22, // make
  0x44, 0x01, 0x80, 0x22, // use
  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 // this is the top line
  };

The graphics of the above matrix will give a monochrome bitmap image in bmp format later.

Such a pile of data is very unintuitive, and we need to analyze it very hard to find that it actually represents a fly. 
If such data are saved as pictures and edited with special tools, it will obviously be much more convenient.
Here's how to do this.
First, create a new picture with the brush program that comes with Windows and name it mask.bmp. When saving, you should select " Monochrome Bitmap ".
In the "Image" -> "Properties" dialog box, set the height and width of the picture to 32. 
Observe the picture with a magnifying glass and edit it. Black corresponds to binary zero (hollowed out), white corresponds to binary one (not hollowed out), save after editing.

Then, you can use the following code to get this Mask array. 

static GLubyte Mask[128];
FILE *fp;
fp = fopen("mask.bmp", "rb");
if( !fp ) exit(0);
// Move the file pointer to this position, so that reading sizeof(Mask) bytes will encounter the end of file
// Note that -(int)sizeof(Mask) is not a good way to write it, but it is valid here
// If you write -sizeof(Mask) directly, because sizeof obtains an unsigned number, there will be a problem with taking the negative sign
if( fseek(fp, -(int)sizeof(Mask), SEEK_END) ) exit(0);
// Read sizeof(Mask) bytes to Mask
if( !fread(Mask, sizeof(Mask), 1, fp) )
    exit(0);
fclose(fp);
Ok, now please edit an image yourself as a mask, and use the above method to obtain the Mask array, and observe the effect after running. 
Description: The factor factor can be set when drawing the dotted line, but the factor factor cannot be set for the hollowing out of the polygon.

Please use the mouse to change the size of the window and observe the change of the hollow effect.

The following lines give two files mask.bmp and mask1.bmp in bmp format:

           

Operating environment:

CentOS7
g++ (GCC) 4.8.5 20150623 (Red Hat 4.8.5-16)
OpenGL implementation vendor's name: VMware, Inc.
Renderer identifier: Gallium 0.4 on llvmpipe (LLVM 3.9, 256 bits)
Version number of OpenGL implementation: 2.1 Mesa 17.0.1
OGLU tool library version: 1.3

Paste the source code:

/**
 * "OpenGL Introductory Tutorial"
 * Points, lines and polygons
 */
#include <GL/glut.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>

/ * Picture point * /
void myDisplay1(void)
{
    glClear(GL_COLOR_BUFFER_BIT);
    glPointSize(5.0f);
    glBegin(GL_POINTS);
    glVertex2f(0.0f, 0.0f);
    glVertex2f(0.5f, 0.5f);
    glEnd();
    glFlush();
}
/*Draw line segment: solid line, dashed line. . . */
void myDisplay2(void)
{
    glClear(GL_COLOR_BUFFER_BIT);
    glEnable(GL_LINE_STIPPLE);
    /*line1*/
    glLineStipple (1.0xAAAA);
    glLineWidth(6.0f);
    glBegin(GL_LINES);
    glVertex2f(0.0f, 0.0f);
    glVertex2f(1.0f, 1.0f);
    glEnd();
    /*line2*/
    glLineStipple (4.0xAAAA);
    glLineWidth(6.0f);
    glBegin(GL_LINES);
    glVertex2f(0.0f, 0.0f);
    glVertex2f(-1.0f, -1.0f);
    glEnd();
    /*line3*/
    glLineStipple(2, 0x00FF);
    glLineWidth(6.0f);
    glBegin(GL_LINES);
    glVertex2f(0.0f, 0.0f);
    glVertex2f(-1.0f, 1.0f);
    glEnd();
    /*line2*/
    glLineStipple(3, 0x0C0F);
    glLineWidth(6.0f);
    glBegin(GL_LINES);
    glVertex2f(0.0f, 0.0f);
    glVertex2f(1.0f, -1.0f);
    glEnd();

    glFlush();
}
/*polygon*/
void myDisplay3(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
    //glFrontFace(GL_CW); // Set the counterclockwise direction as the back face
    glBegin(GL_POLYGON); // Draw a square counterclockwise, at the bottom left
    glVertex2f(-0.5f, -0.5f);
    glVertex2f(0.0f, -0.5f);
    glVertex2f(0.0f, 0.0f);
    glVertex2f(-0.5f, 0.0f);
    glEnd();
    glBegin(GL_POLYGON); // draw a square clockwise, top right
    glVertex2f(0.0f, 0.0f);
    glVertex2f(0.0f, 0.5f);
    glVertex2f(0.5f, 0.5f);
    glVertex2f(0.5f, 0.0f);
    glEnd();
    glFlush();
}

/* hollow polygon */
static GLubyte Mask1[128] =
{ 0x00, 0x00, 0x00, 0x00, // this is the bottom line
  0x00, 0x00, 0x00, 0x00,
  0x03, 0x80, 0x01, 0xC0, // hemp
  0x06, 0xC0, 0x03, 0x60, // annoying
  0x04, 0x60, 0x06, 0x20, // of
  0x04, 0x30, 0x0C, 0x20, // Initial
  0x04, 0x18, 0x18, 0x20, // start
  0x04, 0x0C, 0x30, 0x20, // convert
  0x04, 0x06, 0x60, 0x20, // ,
  0x44, 0x03, 0xC0, 0x22, // no
  0x44, 0x01, 0x80, 0x22, // build
  0x44, 0x01, 0x80, 0x22, // negotiable
  0x44, 0x01, 0x80, 0x22, // make
  0x44, 0x01, 0x80, 0x22, // use
  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 // this is the top line
  };
void myDisplay4(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(Mask1); //Can be given to the Mask that reads the picture mask.bmp
    glRectf(-1.0f, -1.0f, 0.0f, 0.0f); // Draw a square with a hollow effect at the bottom left
    glDisable(GL_POLYGON_STIPPLE);
    glRectf(0.0f, 0.0f, 1.0f, 1.0f); // draw a square without hollow effect on the upper right
    glFlush();
}


int main(int argc, char *argv[])
{
    /*initialization*/
    glutInit(&argc, argv);
    /* Set display mode: RGB color, single buffer */
    glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE);
    /* Set to the center of the window */
    glutInitWindowPosition (100, 100);
    /* set window size */
    glutInitWindowSize (200, 200);
    /* create window */
    glutCreateWindow("Paint1");
    /* set a function */
    glutDisplayFunc(&myDisplay1);
    /* create window */
    glutCreateWindow("Paint2");
    /* set a function */
    glutDisplayFunc(&myDisplay2);
    /* create window */
    glutCreateWindow("Paint3");
    /* set a function */
    glutDisplayFunc(&myDisplay3);
    /* create window */
    glutCreateWindow("Paint4");
    /* set a function */
    glutDisplayFunc(&myDisplay4);

    /* Do a message loop */
    glutMainLoop();
    return 0;
}

Compile and run:

$ make
gcc test.c -lGL -lglut -lGLU -lXmu -Bstatic -Bdyanmic -lm
./a.out

After running, four windows will pop up to draw points, lines, polygons and hollow polygons:


The code and content are from " OpenGL Introductory Tutorial (fine) ", if there is any infringement, please contact to delete it.

Guess you like

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