OpenGL实验一: 绘制小程序

电脑杂谈  发布时间:2020-08-20 03:02:27  来源:网络整理

opengl用鼠标画三角形_opengl画长方体_opengl画机器人

要求: 开发一个绘图程序,用户可以在其中使用鼠标绘制线段,矩形,圆形和三角形. 菜单允许用户选择要绘制的图元.

框架参考

/* globals */
GLsizei wh = 500, ww = 500; /* initial window size */
float xm, ym, xmm, ymm;
int first = 0;
void mouse(int btn, int state, int x, int y)
{
    if(btn==GLUT_LEFT_BUTTON && state==GLUT_DOWN)
    {
        xm = x;
        ym = wh-y;
        glColor3f(0.0, 0.0, 1.0);
        glLogicOp(GL_XOR);
        first = 0;
    }
    if(btn==GLUT_LEFT_BUTTON && state==GLUT_UP)
    {
        if (first == 1)
        {
            glRectf(xm, ym, xmm, ymm);
            glFlush();
        }
        xmm = x;
        ymm = wh-y;
        glColor3f(0.0, 1.0, 0.0);
        glLogicOp(GL_COPY);
        glRectf(xm, ym, xmm, ymm);
        glFlush();
    }
    if(btn==GLUT_RIGHT_BUTTON && state==GLUT_DOWN)  
        exit(0);
}
void move(int x, int y)
{
    if(first == 1)
    {
        glRectf(xm, ym, xmm, ymm);
        glFlush();
    }
    xmm = x;
    ymm = wh-y;
    glRectf(xm, ym, xmm, ymm);
    glFlush();
    first = 1;
}
void reshape(GLsizei w, GLsizei h)
{
    
    /* adjust clipping box */
    
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity(); 
    glOrtho(0.0,(GLdouble)w, 0.0,(GLdouble)h, -1.0, 1.0);
    
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity(); 
    
    /* adjust viewport and clear */
    
    glViewport(0,0,w,h);
    glClearColor(1.0, 1.0, 1.0, 1.0);
    glClear(GL_COLOR_BUFFER_BIT);
    glFlush();
    
    /* set global size for use by drawing routine */
    
    ww = w;
    wh = h; 
}
void init(void)
{
    glViewport(0,0,ww,wh);
    
    /* Pick 2D clipping window to match size of screen window 
    This choice avoids having to scale object coordinates
    each time window is resized */
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity(); 
    glOrtho(0.0,(GLdouble) ww , 0.0,(GLdouble) wh , -1.0, 1.0);
    
    /* set clear color to black and clear window */
    glClearColor(0.0, 0.0, 0.0, 1.0);
    glClear(GL_COLOR_BUFFER_BIT);
    glFlush();  
    glEnable(GL_COLOR_LOGIC_OP);
}
/* display callback required by GLUT 3.0 */
void display(void)
{}
int main(int argc, char** argv)
{
    /***GLUT窗口管理,就当做是固定写法吧***/
    glutInit(&argc,argv);                         //初始化GLUT,在调用其他GLUT函数前调用
    glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);  //设置窗口的显示模式
    glutInitWindowSize(ww, wh);                   //设置窗口的初始宽度和高度,单位为像素,缺省300x300
    glutInitWindowPosition(500, 500)              //窗口左上角相对于屏幕左上角的位置,单位为像素,缺省(0,0) 
    glutCreateWindow("rubber banding");           //创建窗口,标题为title。调用glutMainLoop()之前,窗口不会被显示
    
    init();  //设置OpenGL状态
    /***GLUT事件处理***/
    glutReshapeFunc(reshape);
    glutMouseFunc(mouse);
    glutMotionFunc(move);
    glutDisplayFunc(display);
    glutMainLoop();
}

OpenGL库

首先,您会发现其中一些功能要么以gl开头,要么以glut开头,而以开头的内容代表了哪个库中的函数.

opengl画机器人_opengl画长方体_opengl用鼠标画三角形

OpenGL函数名称格式

OpenGL函数名称格式

GLUT事件处理

我们的界面是使用GLUT库编写的. GLUT使用回调机制进行事件处理.

opengl用鼠标画三角形_opengl画机器人_opengl画长方体

窗口

窗口是显示器上的矩形区域. 窗口内的位置由窗口坐标指定,单位为像素.

请注意原点的位置

因此在绘制时,我们需要在OpenGL命令中将鼠标位置的坐标转换为相应的坐标. 原点位于左上角和左下角. 将其与x坐标进行比较. y坐标是互补的. 您可以通过从窗口的高度(wh)中减去鼠标位置的y坐标来获得OpenGL命令中的坐标.

画一条直线所需的橡皮筋功能

opengl画长方体_opengl用鼠标画三角形_opengl画机器人

此处使用了glLogicOp函数

画一个圆

OpenGL没有提供直接绘制圆的功能,并且实现方法使用多边形对其进行逼近. 大家都知道规则多边形的边越多,就越接近圆形〜

在这里我使用了参数G_TRIANGLE_FAN,这在书中有解释.

拦截部分代码:

opengl用鼠标画三角形_opengl画机器人_opengl画长方体

if (btn == GLUT_LEFT_BUTTON && state == GLUT_UP)
    {
        xmm = x;
        ymm = wh - y;
        float r = sqrt(pow((xm - xmm), 2) + pow((ym - ymm), 2));
        glBegin(GL_TRIANGLE_FAN);
        for (int i = 0; i< 1000; ++i){
            glVertex2f(xm + r*cos(2 * PI / 1000 * i), ym + r*sin(2 * PI / 1000 * i));
        }
        glEnd();
        glFlush();
    }

画一个三角形

一种简单的实现方法: 使用变量保存三点的坐标,每次单击鼠标时记录位置并计数,并在点数达到三时绘制三角形.

拦截部分代码:

void mouse_triangle(int btn, int state, int x, int y)
{
    if (btn == GLUT_LEFT_BUTTON && state == GLUT_DOWN)
    {
        triVertex[ver][0] = x;
        triVertex[ver][1] = wh - y;
        glColor3f(1.0, 0.5, 0.0);
        glBegin(GL_POINTS);
        glVertex2f(triVertex[ver][0], triVertex[ver][1]);
        glEnd();
        glFlush();
        ver++;
        if (ver == 3)
        {   
            //glLogicOp(GL_COPY);//直接用源像素取代目标像素 默认的
            glBegin(GL_TRIANGLES);
            glVertex2f(triVertex[0][0], triVertex[0][1]);
            glVertex2f(triVertex[1][0], triVertex[1][1]);
            glVertex2f(triVertex[2][0], triVertex[2][1]);
            glEnd();
            glFlush();
            ver = 0;
        }
    }
}

添加菜单

使用了以下三个功能,例如:


本文来自电脑杂谈,转载请注明本文网址:
https://www.pc-fly.com/a/bofangqi/article-302702-1.html

    相关阅读
      发表评论  请自觉遵守互联网相关的政策法规,严禁发布、暴力、反动的言论

      热点图片
      拼命载入中...