没什么难的,都是调用OpenGL的API函数去实现即可,却也有一些小的细节处理:
flag:用来标记是否开始交互,因为所有折线(直线段)的第一个端点和最后一个端点都是仅被一条直线占有,而中间的端点因为绘制的是连续折线,都是被两条直线共同占有,这在交互时设定端点坐标和重绘是有一个小细节。看代码中有注释。
- 功能:
左键点击选择端点,鼠标移动控制线的斜率,再次点击第二个端点画线,右击可以清除上一次画的线。
- 效果:
- 代码:
#include <GL/freeglut.h>
struct Line{
GLint x1,y1,x2,y2;
};//一条直线的结构体,包含两个端点
Line line[100];//最多画100条连续折线
int PointNum=0;//端点个数
int Width=400,Height=400;//屏幕的宽高
int flag=0;//需要标记是否已经开始交互画线
void myinit()
{
glClearColor(1.0,1.0,1.0,1.0);
}
void myReshape(GLsizei w,GLsizei h)
{
glViewport(0,0,w,h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0.0,400.0,0.0,400.0);
}
void display()
{
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(1.0,0.0,0.0);
int i=0;
for(i=0;i<PointNum;i++){
glBegin(GL_LINES);
glVertex2f(line[i].x1,line[i].y1);
glVertex2f(line[i].x2,line[i].y2);
glEnd();
}
if(flag==1){//用flag的厉害之处1,在每次移动鼠标事件重绘时最后一条曲线也需要画出来
glBegin(GL_LINES);
glVertex2f(line[PointNum].x1,line[PointNum].y1);
glVertex2f(line[PointNum].x2,line[PointNum].y2);
glEnd();
}
//交换前后缓冲区
glutSwapBuffers();
}
//鼠标点击事件回调函数
void MousePlot(GLint button,GLint action,GLint xMouse,GLint yMouse)
{
if(button==GLUT_LEFT_BUTTON&&action==GLUT_DOWN){
if(flag==0){//用flag的厉害之处2,判定开始交互,第一次选择的点仅被第一条直线占有,不用赋两次值
line[PointNum].x1=xMouse;
line[PointNum].y1=Height-yMouse;
flag=1;
}else{
line[PointNum].x2=xMouse;
line[PointNum].y2=Height-yMouse;
PointNum++;
line[PointNum].x1=xMouse;
line[PointNum].y1=Height-yMouse;
}
}
if(button==GLUT_RIGHT_BUTTON&&action==GLUT_DOWN){
PointNum--;
glutPostRedisplay();
}
}
//鼠标未按下时移动的回调函数
void PassiveMouseMove(GLint xMouse,GLint yMouse)
{
line[PointNum].x2=xMouse;
line[PointNum].y2=Height-yMouse;
glutPostRedisplay();
}
//主函数
int main(int argc, char* argv[])
{
glutInit(&argc, argv);
//初始化OPENGL显示方式
glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGBA);
//设定OPENGL窗口位置和大小
glutInitWindowSize (400, 400);
glutInitWindowPosition (100, 100);
//打开窗口
glutCreateWindow ("交互式绘制贝塞尔曲线");
//调用初始化函数
myinit();
//开始OPENGL的循环
glutDisplayFunc(display);
//设定窗口大小变化的回调函数
glutReshapeFunc(myReshape);
//鼠标响应函数
glutMouseFunc(MousePlot);
glutPassiveMotionFunc(PassiveMouseMove);
glutMainLoop();
return 0;
}