OpenGL学习——入门篇 第二章 基础实例2-2

来源:互联网 发布:全平台主播数据榜单 编辑:程序博客网 时间:2024/06/04 20:29

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 / (2-2*cos(72*Pi/180))
图1 a = 1 / (2-2*cos(72*Pi/180))
sqrt (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 画正弦函数图形

sine function

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();}

stipple_line_10
画个宽度为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)
stipple_0x0FFF
如果我们将其设置为glLineStipple(2, 0xFFFF),会发现变成了一条实线。
stipple_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();}

下图左下角的正方形为逆时针画出的,因此为正面,用填充模式画出;而右上角为顺时针画出,为反面,用线型模式画出
glFrontFace

例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();}

glPolygonStipple

阅读全文
0 0
原创粉丝点击