要实现使用OpenGL的划线方法实现多变形的绘制,就要用到几个OpenGL的基本操作,使用glut库中的方法会更加简单。
几个变量:
#define NUM 200 //折线的最大折线段
int Flag = 0; //标记是否已经开始绘制折线
int RFlag = 0; //标记是否已经完成一个矩形
int Function = 1; //标记选择的功能是画折线还是矩形
int winWidth = 800, winHeight = 600; //窗口的宽度和高度
int Mousex, Mousey; //用于记录当前鼠标的位置
int n = 0; //用于记录折线有几段
int m = 0; //用于记录矩形个数
//线性结构体
struct LineNode {
int x1;
int y1;
int x2;
int y2;
}Line[NUM];
//矩形结构体
struct Rectangle {
int x1;
int y1;
int x2;
int y2;
}Rect[NUM];
static GLsizei iMode = 1;
初始化操作:
void Initial(void) {
glClearColor(1.0f, 1.0f, 1.0f, 1.0f); //设置窗口背景颜色
}
窗口变化响应:
void ChangeSize(int w, int h) { //保存当前窗口的大小
winWidth = w;
winHeight = h;
glViewport(0, 0, w, h); //指定窗口显示区域
//glScalef(0.5, 0.5, 3); 缩放变换
glMatrixMode(GL_PROJECTION); //指定设置投影参数
glLoadIdentity(); //调用单位矩阵,去掉以前的投影参数设置
gluOrtho2D(0.0, winWidth, 0.0, winHeight); //设置投影参数
}
菜单函数:
void ProcessMenu1(int value)
{
Function = value;
n = 0;
Flag = 0;
m = 0;
RFlag = 0;
glutPostRedisplay();
}
显示函数:
void Display()
{
int i, j;
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); //线性模式画图
glClear(GL_COLOR_BUFFER_BIT); //用当前背景色填充窗口
glColor3f(1.0f, 0.0f, 0.0f); //指定当前的绘图颜色
switch(Function){
case 3:
glClear(GL_COLOR_BUFFER_BIT);
}
//绘制折线 最多绘制n条
if (Function == 1) {
for (i = 0; i < n; i++) {
glBegin(GL_LINES);
glVertex2i(Line[i].x1, Line[i].y1);
//如果当前点到第一个点的x、y的像素个数都少于4,则封闭多边形,并结束多边形绘制
if(abs(Line[0].x1 - Line[i].x2) <= 4 && abs(Line[0].y1 - Line[i].y2) <= 4 ){
glVertex2i(Line[0].x1, Line[0].y1);
}else{
glVertex2i(Line[i].x2, Line[i].y2);
}
glEnd();
if(abs(Line[0].x1 - Line[i].x2) <= 4 && abs(Line[0].y1 - Line[i].y2) <= 4 ){
Flag = 0;
for(int cc = 0; cc < n; cc++){
cout << "Line[" << cc << "].x1:" << Line[cc].x1 << endl;
cout << "Line[" << cc << "].y1:" << Line[cc].y1 << endl;
//cout << "Line[" << cc << "].x2:" << Line[cc].x2 << endl;
//cout << "Line[" << cc << "].y2:" << Line[cc].y2 << endl;
}
break;
}
}
if (Flag == 1) {
glBegin(GL_LINES);
glVertex2i(Line[i].x1, Line[i].y1);
glVertex2i(Mousex, Mousey);
glEnd();
}
}
else {
//绘制矩形
for (j = 0; j < m; j++) {
glRecti(Rect[j].x1, Rect[j].y1, Rect[j].x2, Rect[j].y2);
} //动态绘制鼠标动作
if (RFlag == 1) {
glRecti(Rect[j].x1, Rect[j].y1, Mousex, Mousey);
}
}
glutSwapBuffers(); //双缓冲模式用glutSwapBuffers()交换缓冲区 单缓冲模式用glutFlush()交换缓冲区
}
鼠标事件处理:
void MousePlot(GLint button, GLint action, GLint xMouse, GLint yMouse)
{
if (Function == 1) { //线性处理
if (button == GLUT_LEFT_BUTTON && action == GLUT_DOWN) {
if (Flag == 0) {
Flag = 1;
Line[n].x1 = xMouse;
Line[n].y1 = winHeight - yMouse;
}
else {
Line[n].x2 = xMouse;
Line[n].y2 = winHeight - yMouse;
n++;
//折线的第二点作为下一段线的第一个的点
Line[n].x1 = Line[n-1].x2;
Line[n].y1 = Line[n-1].y2;
//printf("%d,%d\n", Line[n].x1, Line[n].y1);
}
}
}
else { //矩形处理
if (button == GLUT_LEFT_BUTTON && action == GLUT_DOWN) {
if (RFlag == 0) {
RFlag = 1;
Rect[m].x1 = xMouse;
Rect[m].y1 = winHeight - yMouse;
}
else {
RFlag=0;
Rect[m].x2 = xMouse;
Rect[m].y2 = winHeight - yMouse;
m++;
glutPostRedisplay();
}
}
}
}
void PassiveMouseMove(GLint xMouse, GLint yMouse) {
Mousex = xMouse;
Mousey = winHeight - yMouse;
//system("cls");
//printf("Mousex:%d, Mousey:%d, yMouse:%d\n", Mousex, Mousey, yMouse);
glutPostRedisplay();
}
主函数:
void MousePlot(GLint button, GLint action, GLint xMouse, GLint yMouse)
{
if (Function == 1) { //线性处理
if (button == GLUT_LEFT_BUTTON && action == GLUT_DOWN) {
if (Flag == 0) {
Flag = 1;
Line[n].x1 = xMouse;
Line[n].y1 = winHeight - yMouse;
}
else {
Line[n].x2 = xMouse;
Line[n].y2 = winHeight - yMouse;
n++;
//折线的第二点作为下一段线的第一个的点
Line[n].x1 = Line[n-1].x2;
Line[n].y1 = Line[n-1].y2;
//printf("%d,%d\n", Line[n].x1, Line[n].y1);
}
}
}
else { //矩形处理
if (button == GLUT_LEFT_BUTTON && action == GLUT_DOWN) {
if (RFlag == 0) {
RFlag = 1;
Rect[m].x1 = xMouse;
Rect[m].y1 = winHeight - yMouse;
}
else {
RFlag=0;
Rect[m].x2 = xMouse;
Rect[m].y2 = winHeight - yMouse;
m++;
glutPostRedisplay();
}
}
}
}
void PassiveMouseMove(GLint xMouse, GLint yMouse) {
Mousex = xMouse;
Mousey = winHeight - yMouse;
//system("cls");
//printf("Mousex:%d, Mousey:%d, yMouse:%d\n", Mousex, Mousey, yMouse);
glutPostRedisplay();
}