OpenGL编程学习实战教程(3)

第2章.编写一个的钟表程序

第一节.绘制基本的几何图形

矩形、三角形、圆形等这些都是经典的几何图形,他们都由线构成的(圆形看成是有很多根短线收尾相连围成的),而线都是点构成的。想起了某一年狗血的高考题=。=....而在OpenGL中画线很简单,你指定线两端的顶点即可。

指定顶点的函数如下:

glVertex2d

glVertex2f

glVertex3f

glVertex3v

每个函数用法各有不同,我们目前的需求是在二维空间中画线,所以重点关注glVertex2f函数。GlVertex2f函数有两个参数x,y,分别表示你所指定的顶点的横纵坐标。

OpenGL编程学习实战教程

x,y坐标的位置如同笛卡尔坐标系一样。

接下来,我们就要开始画线了。OpenGL规定:在你指定顶点之前,你必须调用glBegin()函数,指定顶点之后,必须调用glEnd()。而其中glBegin函数的参数与我们希望它绘制的图形有关。

比如:

glBegin(GL_POINTS);
glVertex2f(0.0f,0.0f);
glVertex2f(0.5f,0.5f);
glEnd();

此时,这两个点会被描绘出来。如果将GL_POINTS改为GL_LINES,一条以这两个点为端点的直线将被画出来。大家可以把上一章中Draw函数改成

voidDraw()
{
    glClear(GL_COLOR_BUFFER_BIT);
    glBegin(GL_POINTS);
    glVertex2f(0.0f,0.0f);
    glVertex2f(0.5f,0.5f);
    glEnd();
    glFlush();
}

运行后就可以看到两个很小的白点。

除此之外,你glBegin()的参数还有很多种,如图:

OpenGL编程学习实战教程

(声明:该图片来自互联网传播,我希望没有涉及到任何的版权问题。如有,我可以马上换掉。)

好的,了解了基本的图形绘制,下面我们就开始着手钟表的绘制。

经过分析,可以发现,钟表其实是由1个大圆(作为表的框架),12个短粗线(作为12个钟点的刻度),3个形状不同的矩阵(分针,时针,秒针)1个点(轴)组成的。

如同,上面说道,圆形看成是有很多根短线收尾相连围成的,那我们现在就先把圆画出来。

glLineWidth(5);
glBegin(GL_LINE_LOOP);
for(i=0; i<100; i++)
{
    glVertex2f(R*cos(2*PI/100*i),R*sin(2*PI/100*i));
                          //觉得数学有压力就多练练
}
glEnd();
glLineWidth(1);

这样一个圆就画好了,实际上,是100根线段连接而成。其中,glLineWidth函数,如同名字一样,他是用于调节接下来OpenGL画出的线的宽度。参数越大,线越粗。使用了过后,记得调用一下glLineWidth(1);不然,以后画出来的线的宽度会一直都是5(这其实和OpenGL的状态机模式有关,如有兴趣就多查查资料)。与此类似的函数还有glPointSize。

接下来,我们就来绘制12个小矩形。

好的,最后,我们再把3根指针画出来就完成了!

指针的位置是和当前的时间有关系,我们这里为了方便,就先把定义3个float变量h,m,s,表示小时,分钟,秒。

h_Length表示时针的长度,h_Angle表示时针相对于0点的偏移量,m_Length,m_Angle,s_Length,s_Angle同理。

h=10;
    m=15;
    s=25;
 h_Length=0.2;
 m_Length=0.3;
 s_Length=0.4;
 count=60;
 s_Angle=s/count;
 count*=60;
 m_Angle=(m*60+s)/count;
 count*=12;
 h_Angle=(h*60*60+m*60+s)/count;
 glLineWidth(1);
 glBegin(GL_LINES);
        glVertex2f(0.0f,0.0f);
        glVertex2f(s_Length*sin(2*PI*s_Angle),s_Length*cos(2*PI*s_Angle));
    glEnd();
    glLineWidth(5);
    glBegin(GL_LINES);
        glVertex2f(0.0f,0.0f);
        glVertex2f(h_Length*sin(2*PI*h_Angle),h_Length*cos(2*PI*h_Angle));
    glEnd();
    glLineWidth(3);
    glBegin(GL_LINES);
        glVertex2f(0.0f,0.0f);
        glVertex2f(m_Length*sin(2*PI*m_Angle),m_Length*cos(2*PI*m_Angle));
    glEnd();
    glLineWidth(1);

最后,我们再画一个点,作为表的中轴。

glBegin(GL_POLYGON);
for(i=0; i<100; i++)
{
    glVertex2f(0.03*cos(2*PI/100*i),0.03*sin(2*PI/100*i));
}
glEnd();

好,glFlush()!

OpenGL编程学习实战教程

大功告成!

附本节全代码:

#include <GL/glut.h>
#include <stdio.h>
#include <math.h>
#include <time.h>
#define PI 3.1415926
void Draw()
{
    int i;
    float R,TR,h_Angle,m_Angle,s_Angle,h,m,s,count,h_Length,m_Length,s_Length;
    R=0.5;
    TR=R-0.05;
    glClear(GL_COLOR_BUFFER_BIT);
    glLineWidth(5);
    glBegin(GL_LINE_LOOP);
 for (i=0; i<100; i++)
    {
        glVertex2f(R*cos(2*PI/100*i),R*sin(2*PI/100*i));
    }
    glEnd();
    glLineWidth(2);
 for (i=0; i<12; i++)
 {
    glBegin(GL_LINES);
            glVertex2f(TR*sin(2*PI/12*i),TR*cos(2*PI/12*i));
            glVertex2f(R*sin(2*PI/12*i),R*cos(2*PI/12*i));
        glEnd();
 }
    glLineWidth(1);
    h=10;
    m=15;
    s=25;
 h_Length=0.2;
 m_Length=0.3;
 s_Length=0.4;
 count=60;
 s_Angle=s/count;
 count*=60;
 m_Angle=(m*60+s)/count;
 count*=12;
 h_Angle=(h*60*60+m*60+s)/count;
 glLineWidth(1);
 glBegin(GL_LINES);
        glVertex2f(0.0f,0.0f);
        glVertex2f(s_Length*sin(2*PI*s_Angle),s_Length*cos(2*PI*s_Angle));
    glEnd();
    glLineWidth(5);
    glBegin(GL_LINES);
        glVertex2f(0.0f,0.0f);
        glVertex2f(h_Length*sin(2*PI*h_Angle),h_Length*cos(2*PI*h_Angle));
    glEnd();
    glLineWidth(3);
    glBegin(GL_LINES);
        glVertex2f(0.0f,0.0f);
        glVertex2f(m_Length*sin(2*PI*m_Angle),m_Length*cos(2*PI*m_Angle));
    glEnd();
    glLineWidth(1);

glBegin(GL_POLYGON);
 for (i=0; i<100; i++)
    {
        glVertex2f(0.03*cos(2*PI/100*i),0.03*sin(2*PI/100*i));
    }
    glEnd();
    glFlush();
}
int main(int argc, char *argv[])
{
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE);
    glutInitWindowPosition(100, 100);
    glutInitWindowSize(400, 400);
    glutCreateWindow("HelloOpenGL");
    glutDisplayFunc(&Draw);
    glutMainLoop();
    return 0;
}

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:http://www.heiqu.com/1dd33752d840e115225e85aedc5cc649.html