Opengl basic learning topic (3) Several polygon painting styles, opengl topic

Source: Internet
Author: User
Tags 0xc0 bmp image

Opengl basic learning topic (3) Several polygon painting styles, opengl topic

Digress

The reason why smart people cannot succeed is that they lack perseverance.

-- Isaac Newton (January 4-17, 1643-March 31) UK


 

 

 


 

 


It may be understood that when you want to take a deeper step, persistence, hard work, and intelligence are indispensable. I would like to pay tribute to you with a straight waist. May you still be in heaven

Still thinking and running.

 

Body

In the second lesson, we learned how to draw ry, But if you write a few more programs, you will find that there are still some depressing points.

For example, the dot is too small to be clearly visible; the straight line is too thin and uncomfortable; or you want to draw a dotted line, but you do not know how to use a lot of short lines, or even a combination of dots.

These problems will be solved in this lesson.

The following describes vertices, straight lines, and polygon.

1. Points

The default vertex size is 1 pixel, but it can also be changed. The changed command is glPointSize. 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 the specific OpenGL implementation, the vertex size has a limit. If the SET size exceeds the maximum value, the setting may be faulty .)

Here, let's take the Window code as an example to explain the above function compiler behavior as follows:

// Specific function prototype declaration
WINGDIAPI void APIENTRY glPointSize (GLfloat size);

/ *
  * APIENTRY is a macro that sets the compiler's behavior. Essentially __stdcall
  *
  * __ stdcall is a type of function calling convention, which mainly constrains two things:
  * 1. Parameter passing order
  * 2. Who clears the call stack (calling function or called function)
  * 3. Function names (at the compiler level) are automatically preceded by an underscore, followed by an @ sign, followed by the parameter size
  *
  * The default function in C is __cdecl
  * Each function that calls it contains code to clear the stack, so the resulting executable file size will be larger than calling the _stdcall function.
  * Functions are pushed from right to left.
  * Note: For member functions with variable parameters, always use the __cdecl conversion method.
  * /
#define WINAPI __stdcall
#define WINAPIV __cdecl
#define APIENTRY WINAPI

 

The actual use of glPointSize is as follows:

#include <glut.h>

/ *
  *
  * Here is the main function for drawing
  * /
static void __display (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 straight lines

(1) the width of a line can be specified:

Void glLineWidth (GLfloat width );

Its usage is similar to glPointSize.

(2) Draw a dotted line.

First, use GL_LINE_STIPPLE; to start the dotted line mode (glDisable (GL_LINE_STIPPLE ).

Then, use glLineStipple to set the dotted line style.

Void glLineStipple (GLint factor, GLushort pattern );

Pattern is a 16-length sequence composed of 1 and 0. Starting from the percentile, if it is 1, the factor points that should be drawn next on the straight line will be painted as solid; if it is 0, the factor points that should be drawn next in the straight line will be painted as virtual points.

Let's talk more about it.

glEnable (GL_LINE_STIPPLE);
glLineStipple (1, Ox3F07);
// At this time, the mode is Ox3F07 (the binary form is 0011111100000111).
// The straight line it draws looks like this:
// Draw 3 pixels in succession, then leave 5 pixels in a row, then draw 6 pixels in a row, and leave the last two pixels blank (note that it starts with the low bit first).
// If factor is 2, then this pattern is expanded to:
// Draw 6 pixels consecutively, then leave 10 consecutive pixels blank, then draw 12 pixels consecutively, and leave the last 4 pixels blank.
// If stippling is not enabled, OpenGL will automatically treat pattern as OxFFFF and factor as 1.

The code for a more detailed example is as follows:

#include <glut.h>

// Drawing function
static void __display (void)
{
     glClear (GL_COLOR_BUFFER_BIT);
     glEnable (GL_LINE_STIPPLE); // Turn on dotted line mode
     glLineStipple (2,0x0F0F); // style of dotted line
     glLineWidth (10.f);

     // Draw a line
     glBegin (GL_LINES);
     glVertex2f (0.0f, 0.0f);
     glVertex2f (0.5f, 0.5f);
     glEnd ();

     glDisable (GL_LINE_STIPPLE); // Turn off dotted line mode
     glFlush ();
}

3. Polygon

Polygon has many contents. We will introduce the following four aspects.

(1) Two sides of a polygon and the method of drawing the polygon.

Although we have not yet used 3D coordinates for drawing, it is necessary to establish some 3D concepts.

From a three-dimensional perspective, a polygon has two sides. You can set different painting methods for each surface: Fill, draw only edge contour lines, and draw only vertices. "fill" is the default method.

You can set different methods for the two sides.

GlPolygonMode (GL_FRONT, GL_FILL); // you can specify the filling mode as the frontend.

GlPolygonMode (GL_BACK, GL_LINE); // you can specify the reverse side as the edges.

GlPolygonMode (GL_FRONT_AND_BACK, GL_POINT); // you can specify the vertex rendering mode for both sides.

(2) reverse

It is generally agreed that "the vertex appears on the screen in a counter-clockwise order" is "Front", and the other side is "Opposite ".

The surface of common objects in life can usually be expressed as "front" and "back", and "reasonable ".

(Please find a more transparent mineral water bottle, draw a circle along the clockwise toward your side, and indicate the direction of the painting, then convert the back to the front, draw a similar circle, experience "front" and "back ".

You will find that it is in your direction, the outside of the bottle is the front, and the back is in your direction, the inside of the bottle is the front. It is opposite to your inner and back to your outer.

In this way, it also belongs to the "outside of the bottle" surface, but some places are positive and some places are opposite ).

But there are some special surfaces. For example, you can use the "front" or "back" to display the "mbius belt" (Bing it yourself.

The glFrontFace function can be used to exchange the concepts of "front" and "back.

GlFrontFace (GL_CCW); // sets the CCW direction to "Front", and the CCW is CounterClockWise, which is counter-clockwise.

GlFrontFace (GL_CW); // set the CW direction to "Front", CW is ClockWise, ClockWise

The following is an example program. Use it to replace the _ display function in the previous tutorial, change glFrontFace (GL_CCW) to glFrontFace (GL_CW), and observe the changes in the results.

#include <glut.h>

// Drawing function
static void __display (void)
{
     glClear (GL_COLOR_BUFFER_BIT);

     glFrontFace (GL_CCW); // Set counterclockwise to front
     glPolygonMode (GL_FRONT, GL_FILL); // Set the front face to fill mode
     glPolygonMode (GL_BACK, GL_LINE); // Set the reverse side to linear mode

     // Draw a square counterclockwise first, at the bottom left
     glBegin (GL_POLYGON);
     glVertex2f (-0.5, -0.5f);
     glVertex2f (0.0f, -0.5f);
     glVertex2f (0.0f, 0.0f);
     glVertex2f (-0.5f, 0.0f);
     glEnd ();

     // Draw a square clockwise, at the top right
     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) Remove the polygon surface

In 3D space, although a polygon has two sides, we cannot see those Polygon on the back. While some polygon are positive, they are blocked by other polygon. If you treat invisible polygon as visible polygon, it will undoubtedly reduce the processing efficiency of the image. In this case, unnecessary surfaces can be removed.

First, use GL_CULL_FACE; to enable the removal function (glDisable (GL_CULL_FACE)

Then, use glCullFace for removal.

The glCullFace parameter can be GL_FRONT, GL_BACK, or GL_FRONT_AND_BACK, indicating that the front, back, and front sides of the polygon are removed respectively.

Note: The remove function only affects polygon, but does not affect vertices and straight lines. For example, after glCullFace (GL_FRONT_AND_BACK) is used, all polygon will be removed, so only vertices and straight lines are seen.

(4) hollow Polygon

A straight line can be painted as a dotted line, while a polygon can be hollowed out.

First, use GL_POLYGON_STIPPLE; to start the hollow-out mode (glDisable (GL_POLYGON_STIPPLE ).

Then, use glPolygonStipple to set the hollow-out style.

Void glPolygonStipple (const GLubyte * mask );

The parameter mask points to a space of 128 bytes, which indicates how to hollow out a 32*32 rectangle. Where: the first byte indicates the left-to-right (or right-to-left, which can be changed) whether eight pixels are hollowed out (1 indicates not hollowed out, show this pixel; 0 indicates hollow out, and the color behind it is displayed). The last byte indicates whether the eight pixels at the top right are hollow out.

This is a simple method for defining mask.

Win + R => mspaint + Enter => set the canvas pixel to 32*32 => edit by yourself => Save As my.bmp => the program reads the file and converts it to mask

The following is an example of Opengl:

#include <sc_head.h>
#include <glut.h>

static GLubyte __masks [] = {
    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, // early
    0x04, 0x18, 0x18, 0x20, // start
    0x04, 0x0C, 0x30, 0x20, //
    0x04, 0x06, 0x60, 0x20, //,
    0x44, 0x03, 0xC0, 0x22, // no
    0x44, 0x01, 0x80, 0x22, // build
    0x44, 0x01, 0x80, 0x22, // negotiation
    0x44, 0x01, 0x80, 0x22, // enable
    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
};

// bmp image creation function
void bmp_create (GLubyte mask [], int len);

// screen drawing function
void display (void);


#define _STR_BMP "fly.bmp"

int main (int argc, char * argv [])
{
    // here first create a bmp
    bmp_create (__ masks, sizeof __masks);

    glutInit (& argc, argv); // Initialize the glut environment
    glutInitDisplayMode (GLUT_RGB | GLUT_SINGLE); // Set the window to draw in RGB mode and single buffer mode
    glutInitWindowPosition (500,500);
    glutInitWindowSize (300,300);

    glutCreateWindow (argv [0]); // Initialize the startup window
    glutDisplayFunc (display);

    glutMainLoop (); // loop wait function until the window created by glut is closed

    return 0;
}

// bmp image creation function
void
bmp_create (GLubyte mask [], int len)
{
    FILE * bmp = NULL;

    if (NULL == mask || len <= 0)
        ERR_EXIT ("check params error [NULL == mask || len <= 0].");

    if ((bmp = fopen (_STR_BMP, "wb")) == NULL) // write it a bit
        ERR_EXIT ("fopen error!");
    // file write
    fwrite (mask, sizeof (GLubyte), len, bmp);

    fclose (bmp) ;;
}

// screen drawing function
void
display (void)
{
    GLubyte mask [sizeof __masks];
    // Read the contents of the file first

    FILE * bmp = NULL;
    if ((bmp = fopen (_STR_BMP, "rb")) == NULL) // write it a little bit for practice
        ERR_EXIT ("fopen error!");
    // file write
    fread (mask, sizeof (GLubyte), sizeof mask, bmp);

    fclose (bmp);

    // Start drawing here
    glClear (GL_COLOR_BUFFER_BIT);
    glEnable (GL_POLYGON_STIPPLE); // Enable hollow mode
    glPolygonStipple (mask); // Set the hollow style

    glRectf (-0.5f, -0.5f, 0.0f, 0.0f); // Draw a square with a hollowed out effect at the bottom left
    glDisable (GL_POLYGON_STIPPLE); // Close hollow out mode
    glRectf (0.0f, 0.0f, 0.5f, 0.5f); // Draw a square with no hollowing effect to the upper right

    glFlush ();

} 

The last one is as follows:


 

Summary

This lesson describes how to draw geometric figures.

Point to set the size.

You can set the width of a straight line. You can draw a straight line as a dotted line.

You can set the two sides of a polygon. In a 3D space, invisible polygon can be removed. You can draw a filled Polygon into a hollow style.

Understanding these details will make us more comfortable in some image rendering.

In addition, writing some data to files outside the program and editing it with special tools can sometimes be more convenient.

 

As a cainiao, you are welcome to discuss and correct it. I hope it will be more interesting now. Come on.

 


Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.