2-2 例1
画一个圆
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();
}
例2 画一个五角星
http://www.cnblogs.com/crazyxiaom/articles/2073586.html
中的计算方法是:
/*
设五角星的五个顶点分布位置关系如下:
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);
五个点的坐标就可以通过以上四个量和一些常数简单的表示出来
*/
这一步很奇怪,我的算法是a^2 + a^2 + 2*a^2cos(72/180 * π) = 1
因此,我们计算出来的结果应该是GLfloat a = sqrt (1 / (2 - 2 * cos(72 * Pi / 180)));
而非a = 1 / (2-2*cos(72*Pi/180));
画出来的结果对比图如下:
图1 a = 1 / (2-2*cos(72*Pi/180))
图2 a = sqrt (1 / (2 - 2 * cos(72 * Pi / 180)))
按照后面几个点选取的公式,画出来的肯定是五角星,只是其胖瘦不同罢了,也可能上窄下宽,例如可以强制a = 0.5进行试验。
源码如下:
const GLfloat Pi = 3.1415926536f;
void myDisplay(void)
{
GLfloat a = sqrt (1 / (2 - 2 * cos(72 * Pi / 180)));
//GLfloat a = 1 / (2 - 2 * cos(72 * Pi / 180));
//GLfloat a = 0.5;
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();
}
例3 画正弦函数图形
const GLfloat factor = 0.05f;
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);
//理解为factor * (横坐标,纵坐标) = (横坐标 * factor + 纵坐标 * factor)
//即 (x*factor, sin(x)*factor)
}
glEnd();
glFlush();
}
例4 点、线
size必须大于0.0f,默认值为1.0f,单位为“像素”。
void myDisplay(void)
{
glClear(GL_COLOR_BUFFER_BIT);
glPointSize(10.0f);
glBegin(GL_POINTS);
glVertex2f(0.0f, 0.0f);
glVertex2f(0.5f, 0.5f);
glEnd();
glFlush();
}
画个宽度为10的虚线段
void myDisplay(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(0.5f, 0.5f);
glEnd();
glFlush();
}
体会下这个glLineStipple(2, 0x0F0F),我们将其改为glLineStipple(2, 0x0FFF)
如果我们将其设置为glLineStipple(2, 0xFFFF),会发现变成了一条实线。
例5 多边形的两面及绘制
如果设置顺时针为正面,则填写GL_CW(Clock Wise),
如果设置逆时针为正面,则填写GL_CCW(CounterClockWise)
void myDisplay(void)
{
glClear(GL_COLOR_BUFFER_BIT);
glPolygonMode(GL_FRONT, GL_FILL); // 设置正面为填充模式
glPolygonMode(GL_BACK, GL_LINE); // 设置反面为线形模式
glFrontFace(GL_CCW); // 设置逆时针方向为正面
glBegin(GL_POLYGON); // 按逆时针绘制一个正方形,在左下方
glVertex2f(-0.5f, -0.5f);
glVertex2f(0.0f, -0.5f);
glVertex2f(0.0f, 0.0f);
glVertex2f(-0.5f, 0.0f);
glEnd();
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();
}
下图左下角的正方形为逆时针画出的,因此为正面,用填充模式画出;而右上角为顺时针画出,为反面,用线型模式画出
例6 镂空多边形
这里面我们参考前人博客:http://www.cnblogs.com/crazyxiaom/articles/2073586.html
中的大数组,我发现用fopen打开总会出错,错误代码如下:
线程 0x4830 已退出,返回值为 0 (0x0)。
线程 0x5bbc 已退出,返回值为 0 (0x0)。
线程 0x51bc 已退出,返回值为 0 (0x0)。
线程 0x5b28 已退出,返回值为 0 (0x0)。
应该是fopen失败了,等周末有空我再研究下它,这不重要不影响咱们镂空概念的学习。
static GLubyte Mask[128] =
{
0x00, 0x00, 0x00, 0x00, // 这是最下面的一行
0x00, 0x00, 0x00, 0x00,
0x03, 0x80, 0x01, 0xC0, // 麻
0x06, 0xC0, 0x03, 0x60, // 烦
0x04, 0x60, 0x06, 0x20, // 的
0x04, 0x30, 0x0C, 0x20, // 初
0x04, 0x18, 0x18, 0x20, // 始
0x04, 0x0C, 0x30, 0x20, // 化
0x04, 0x06, 0x60, 0x20, // ,
0x44, 0x03, 0xC0, 0x22, // 不
0x44, 0x01, 0x80, 0x22, // 建
0x44, 0x01, 0x80, 0x22, // 议
0x44, 0x01, 0x80, 0x22, // 使
0x44, 0x01, 0x80, 0x22, // 用
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 // 这是最上面的一行
};
void myDisplay(void)
{
/* static GLubyte Mask[1024];
FILE *fp;
fp = fopen("star.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(Mask);
glRectf(-0.5f, -0.5f, 0.0f, 0.0f); // 在左下方绘制一个有镂空效果的正方形
glDisable(GL_POLYGON_STIPPLE);
glRectf(0.0f, 0.0f, 0.5f, 0.5f); // 在右上方绘制一个无镂空效果的正方形
glFlush();
}