
要求: 开发一个绘图程序,用户可以在其中使用鼠标绘制线段,矩形,圆形和三角形. 菜单允许用户选择要绘制的图元.
框架参考
/* 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函数名称格式
GLUT事件处理
我们的界面是使用GLUT库编写的. GLUT使用回调机制进行事件处理.

窗口
窗口是显示器上的矩形区域. 窗口内的位置由窗口坐标指定,单位为像素.
请注意原点的位置
因此在绘制时,我们需要在OpenGL命令中将鼠标位置的坐标转换为相应的坐标. 原点位于左上角和左下角. 将其与x坐标进行比较. y坐标是互补的. 您可以通过从窗口的高度(wh)中减去鼠标位置的y坐标来获得OpenGL命令中的坐标.
画一条直线所需的橡皮筋功能

此处使用了glLogicOp函数
画一个圆
OpenGL没有提供直接绘制圆的功能,并且实现方法使用多边形对其进行逼近. 大家都知道规则多边形的边越多,就越接近圆形〜
在这里我使用了参数G_TRIANGLE_FAN,这在书中有解释.
拦截部分代码:

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
武器的火力强度