第2章.编写一个的钟表程序
第一节.绘制基本的几何图形
矩形、三角形、圆形等这些都是经典的几何图形,他们都由线构成的(圆形看成是有很多根短线收尾相连围成的),而线都是点构成的。想起了某一年狗血的高考题=。=....而在OpenGL中画线很简单,你指定线两端的顶点即可。
指定顶点的函数如下:
glVertex2d
glVertex2f
glVertex3f
glVertex3v
每个函数用法各有不同,我们目前的需求是在二维空间中画线,所以重点关注glVertex2f函数。GlVertex2f函数有两个参数x,y,分别表示你所指定的顶点的横纵坐标。
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()的参数还有很多种,如图:
(声明:该图片来自互联网传播,我希望没有涉及到任何的版权问题。如有,我可以马上换掉。)
好的,了解了基本的图形绘制,下面我们就开始着手钟表的绘制。
经过分析,可以发现,钟表其实是由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()!
大功告成!
附本节全代码:
#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;
}