[Turn] OpenGL Introduction - Lesson 2

This course is about drawing simple geometric figures, but let's get acquainted with some concepts before actually drawing.

1. Points, lines and polygons
We know the concepts of points, lines and polygons in mathematics (specifically, geometry), but these concepts will be different in computers.
A mathematical point has only position, not size. But in the computer, no matter how the calculation accuracy is improved, it can never represent an infinitesimal point. On the other hand, no matter how precise a graphics output device (eg a monitor) is, it can never output an infinitesimal point. In general, a point in OpenGL will be drawn as a single pixel (the concept of a pixel, please search for it yourself~), although it may be small enough, it will not be infinitely small. On the same pixel, OpenGL can draw many points with only slightly different coordinates, but the exact color of that pixel will depend on the OpenGL implementation. Of course, paying too much attention to details is just cutting corners, and we don't have to spend too much energy on "how to draw multiple points to the same pixel".
Likewise, mathematical lines have no width, but OpenGL lines do. At the same time, the straight line of OpenGL must be of finite length, not infinite like a mathematical concept. It can be considered that OpenGL's "straight line" concept is close to the mathematical "line segment", which can be determined by two endpoints.
A polygon is a closed area formed by connecting multiple line segments end to end. OpenGL stipulates that a polygon must be a "convex polygon" (which is defined as: the line segment determined by any two points in the polygon is within the polygon, and it can also be deduced that a convex polygon cannot be hollow). A polygon can be determined by the endpoints of its edges (called vertices here). (Note: If the polygon used is not convex, the final output effect is undefined - OpenGL relaxes the check for efficiency, which may lead to display errors. To avoid this error, try to use triangles, because triangles are all convex polygon)

It is conceivable that through points, lines and polygons, various geometric figures can be combined. You can even think of an arc as a series of short straight line segments that are short enough that their length is less than the width of a pixel. In this way, arcs and circles can also be represented. We can also form a "surface" by connecting small polygons that lie on different planes.

 

2. Specifying vertices in OpenGL
From the above discussion, we can know that "point" is the basis of everything.
How to specify a point? OpenGL provides a series of functions. They all start with glVertex, followed by a number and 1~2 letters. For example:
glVertex2d
glVertex2f
glVertex3f
glVertex3fv
and so on.
The number represents the number of parameters, 2 means there are two parameters, 3 means three, and 4 means four (I know it's a bit wordy~).
The letter indicates the type of the parameter, s indicates a 16-bit integer (this type is defined as GLshort in OpenGL),
                  i indicates a 32-bit integer (this type is defined as GLint and GLsizei in OpenGL), and
                  f indicates a 32-bit floating point number (in OpenGL, the This type is defined as GLfloat and GLclampf), and
                  d represents a 64-bit floating point number (this type is defined as GLdouble and GLclampd in OpenGL).
                  v indicates how the passed parameters will use pointers, see the example below.
These functions are identical except for the type and number of parameters. For example, the functions of the following five code segments are equivalent:
(1) glVertex2i(1, 3);
(2) glVertex2f(1.0f, 3.0f);
(3) glVertex3f(1.0f, 3.0f, 0.0f) ;
(4) glVertex4f(1.0f, 3.0f, 0.0f, 1.0f);
(5) GLfloat VertexArr3[] = {1.0f, 3.0f, 0.0f};
     glVertex3fv(VertexArr3);
We will use glVertex* to represent this series of functions in the future.
Note: Many functions of OpenGL are in this form, a same prefix plus a parameter description mark, which will be more experienced with the deepening of learning.

 

3. Start drawing
Suppose now that I have specified a number of vertices, how does OpenGL know what I want to do with these vertices? Is it drawn one by one, or is it connected in a line? Or form a polygon? Or do something else?
To solve this problem, OpenGL requires that the command to specify the vertex must be included after the glBegin function and before the glEnd function (otherwise the specified vertex will be ignored). And it is up to glBegin to specify how to use these points.
For example I write:
glBegin(GL_POINTS);
    glVertex2f(0.0f, 0.0f);
    glVertex2f(0.5f, 0.0f);
glEnd();
then these two points will be drawn separately. If you replace GL_POINTS with GL_LINES, the two points will be considered as the two endpoints of a line, and OpenGL will draw a line.
We can also specify more vertices and draw more complex shapes.
On the other hand, in addition to GL_POINTS and GL_LINES, glBegin supports GL_LINE_STRIP, GL_LINE_LOOP, GL_TRIANGLES, GL_TRIANGLE_STRIP, GL_TRIANGLE_FAN, etc. The general effect of each method is shown in the following figure:

Statement: The picture is from www.opengl.org, the picture is Figures for the book "OpenGL Programming Guide", since the old edition of the book (first edition, 1994) has been circulated on the Internet, I hope that the copyright issue is not touched.

I'm not going to make a fuss about glBegin's various ways. You can try to change the way of glBegin and the position of vertices to generate some interesting patterns.

Program code:
void myDisplay(void)
{
    glClear(GL_COLOR_BUFFER_BIT);
    glBegin(  /* Fill in your desired mode here */  );
        /* Use glVertex* series of functions here */
        /* Specify your desired vertex position */
    glEnd();
    glFlush( );
}
Change this code to your liking, then replace the myDisplay function in Lesson 1 with it, and it will compile and run.

 

Three examples
Example 1. Draw a circle
/*
regular quadrilateral, regular pentagon, regular hexagon, ..., until the regular n-gon, when n is larger, the graph is closer to a circle
when n is large to a certain extent After that, the human eye will not be able to distinguish it from a real circle.
At this time, we have successfully drawn a "circle"
(Note: There are many ways to draw a circle, here is a simpler but less efficient one )
Try to modify the value of const int n below, and observe the change of output when n=3, 4, 5, 8, 10, 15, 20, 30, 50, etc. Change
GL_POLYGON to GL_LINE_LOOP, GL_POINTS and other methods , observe the change of the output
*/

#include <math.h>
const int n = 20;
const GLfloat R = 0.5f;
const GLfloat Pi = 3.1415926536f;
void myDisplay(void)
{
    int i;
    glClear(GL_COLOR_BUFFER_BIT);
    glBegin(GL_POLYGON);
    for(i=0; i<n; ++i)
        glVertex2f(R*cos(2*Pi/n*i), R*sin(2*Pi/n*i));
    glEnd();
    glFlush();
}

例二、画一个五角星
/*
设五角星的五个顶点分布位置关系如下:
     A
 E       B

   D   C
首先,根据余弦定理列方程,计算五角星的中心到顶点的距离a
(假设五角星对应正五边形的边长为.0)
a = 1 / (2-2*cos(72*Pi/180));
然后,根据正弦和余弦的定义,计算B的x坐标bx和y坐标by,以及C的y坐标
(假设五角星的中心在坐标原点)
bx = a * cos(18 * Pi/180);
by = a * sin(18 * Pi/180);
cy = -a * cos(18 * Pi/180);
五个点的坐标就可以通过以上四个量和一些常数简单的表示出来
*/

#include <math.h>
const GLfloat Pi = 3.1415926536f;
void myDisplay(void)
{
    GLfloat a = 1 / (2-2*cos(72*Pi/180));
    GLfloat bx = a * cos(18 * Pi/180);
    GLfloat by = a * sin(18 * Pi/180);
    GLfloat cy = -a * cos(18 * Pi/180);
    GLfloat
        PointA[2] = { 0, a },
        PointB[2] = { bx, by },
        PointC[2] = { 0.5, cy },
        PointD[2] = { -0.5, cy },
        PointE[2] = { -bx, by };

    glClear(GL_COLOR_BUFFER_BIT);
    // 按照A->C->E->B->D->A的顺序,可以一笔将五角星画出
    glBegin(GL_LINE_LOOP);
        glVertex2fv(PointA);
        glVertex2fv(PointC);
        glVertex2fv(PointE);
        glVertex2fv(PointB);
        glVertex2fv(PointD);
    glEnd();
    glFlush();
}

 

 

例三、画出正弦函数的图形
/*
由于OpenGL默认坐标值只能从-1到1,(可以修改,但方法留到以后讲)
所以我们设置一个因子factor,把所有的坐标值等比例缩小,
这样就可以画出更多个正弦周期
试修改factor的值,观察变化情况
*/

#include <math.h>
const GLfloat factor = 0.1f;
void myDisplay(void)
{
    GLfloat x;
    glClear(GL_COLOR_BUFFER_BIT);
    glBegin(GL_LINES);
        glVertex2f(-1.0f, 0.0f);
        glVertex2f(1.0f, 0.0f);        // 以上两个点可以画x轴
        glVertex2f(0.0f, -1.0f);
        glVertex2f(0.0f, 1.0f);        // 以上两个点可以画y轴
    glEnd();
    glBegin(GL_LINE_STRIP);
    for(x=-1.0f/factor; x<1.0f/factor; x+=0.01f)
    {
        glVertex2f(x*factor, sin(x)*factor);
    }
    glEnd();
    glFlush();
}

 

 

小结
本课讲述了点、直线和多边形的概念,以及如何使用OpenGL来描述点,并使用点来描述几何图形。
大家可以发挥自己的想象,画出各种几何图形,当然,也可以用GL_LINE_STRIP把很多位置相近的点连接起来,构成函数图象。如果有兴趣,也可以去找一些图象比较美观的函数,自己动手,用OpenGL把它画出来。

转自http://blog.csdn.net/andyhuabing/article/details/6603151

Guess you like

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