openGL下的”橡皮筋“技术(多边形绘制)

要实现使用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(); 
}


 

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

jackie_05

oo

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值