连续线鼠标拖动

时间:2013-10-27 05:33:52

标签: opengl window mouseevent glut

我正在制作一个基本的OpenGl程序,这是我的周末项目 说明: 如果我在窗口屏幕上拖动鼠标,那么在我释放按钮(左)后,会出现一条线,显示拖动鼠标的路径,圆圈应该从开始结束。
我的代码非常好但问题是绘制的线不是连续的[而是虚线],这可能是因为OS屏幕到OpenGL屏幕的映射。 所以有什么方法可以建立一条连续的线路或纠正我如果我做错了什么这是我的代码:

#include <iostream>
#include <glut.h>
#include <string.h>
#define WIDTH 600
#define HEIGHT 600

using namespace std;

double arr[5000][4];
int z=0;
int flag=0;
float radius=0.03;
int ptr=0;
int faltu_bit=1;
float color[3][3]={{1.0,1.0,1.0},{1.0,1.0,0.0},{0.0,1.0,0.0}};

void drawText(char *str,float x,float y,int id) 
{
    int i;
    int len=strlen(str);
    //glLoadIdentity();
    glColor3f(color[id][0],color[id][1],color[id][2]);
    glRasterPos2f(x,y);
    for(i=0;i<len;i++)
        glutBitmapCharacter(GLUT_BITMAP_TIMES_ROMAN_24,str[i]);
}


void init()
{
    glClearColor( 0.0, 0.0, 0.0, 1.0);
    glMatrixMode( GL_PROJECTION);
    gluOrtho2D(0.0,WIDTH,0.0,HEIGHT);
    memset(arr,0,5000);
    glPointSize(20.0);
}

void resetAll()
{ 
    memset(arr,0,5000);
    z=0;
} 

///OPENGL MAPPING///
float getOpenGLX(int x)
{
    double ox = x/ (double)WIDTH*(WIDTH);
    return ox;
}

float getOpenGLY(int y)
{
    double oy = (1 - y/ (double) HEIGHT)*HEIGHT;
    return oy;
}

void drawPoints()
{ 
    glBegin( GL_POINTS );
    glColor3f( 0.0,1.0,0.0 );
    for ( int i = 0; i < z; i++ )
    {
        glVertex2f( arr[i][0],arr[i][1]);
    }
    glEnd();
}

void drawBall(float x,float y)
{
    glBegin( GL_POINTS);
    glColor3f( 1.0,1.0,0.0 );
    glVertex2f(x,y);
    glEnd();
}

void drawLines()
{
    glBegin(GL_LINES);
    glColor3f(1.0,0.0,0.0);
    for(int i=0;i<z;i++)
    {
        glVertex2f(arr[i][0],arr[i][1]);
    }
    glEnd();
}



void addValue(int x,int y)
{
    arr[z][0]=getOpenGLX(x);
    arr[z++][1]=getOpenGLY(y);
} 

void trackBall()
{
    drawPoints();
}


void myDisplay()
{
    glClear( GL_COLOR_BUFFER_BIT);
    if(!flag)
    {
        drawLines();
        if(!faltu_bit)
        drawBall(arr[ptr][0],arr[ptr][1]);
    }
    if(faltu_bit)
    {
        drawText("Project by: Adil Ansar [10 CSS-32]",50.0,500.0,0);
        drawText("Welcome",250.0,300.0,1);
        drawText("Drag the Mouse Any Where in the Window to see the Path",10.0,200.0,2);
    }
    glutSwapBuffers();
    glutPostRedisplay();
    glFlush();
}


void myMouseStat(int button,int state,int x, int y)
{
    if(button==GLUT_LEFT_BUTTON && state==GLUT_DOWN)
    {
        if(!flag)
        {
            if(faltu_bit)
            {
                faltu_bit=0;
            }
            resetAll();
            flag=1;
        }
    }
    else if(button==GLUT_LEFT_BUTTON && state==GLUT_UP)
    {
        if(flag)
        { 
            ptr=0;
            flag=0;
        }
    }
}


void myPressedMove(int x,int y)
{
    if(flag)
    {
        addValue(x,y);
    }
}



void myTimer(int t)
{
    if(ptr!=z)
    {
         ptr++;
    }
    else
{
    ptr=0;
}
    glutTimerFunc(100,myTimer,0);
}

int main( int argc, char ** argv)
{
    glutInit( &argc, argv);
    glutInitDisplayMode( GLUT_DOUBLE| GLUT_RGB);
    glutInitWindowPosition( 100, 100);
    glutInitWindowSize(WIDTH,HEIGHT);
    glutCreateWindow( "Testing");
    init();
    glutDisplayFunc(myDisplay);
    glutMouseFunc(myMouseStat);
    glutMotionFunc(myPressedMove);
    glutTimerFunc(100,myTimer,0);
    glutMainLoop();
    return 0;
}


这就是我得到的:

My code output

1 个答案:

答案 0 :(得分:4)

在此代码中

void drawLines()
{
    glBegin(GL_LINES);
    glColor3f(1.0,0.0,0.0);
    for(int i=0;i<z;i++)
    {
        glVertex2f(arr[i][0],arr[i][1]);
    }
    glEnd();
}

GL_LINES是一种绘图模式,其中两个连续的顶点构成一个线段。然后接下来的两个等等。您正在绘制的是线条;将GL_LINES替换为GL_LINE_STRIP将为您提供预期的结果。

旁注:你应该放弃使用立即模式(glBegin,glVertex,glEnd)。它很慢,工作繁琐,从长远来看可以成为一个主要的PITA。至少使用顶点数组; 15年来,他们一直是推荐提供几何数据的方法。此外,它使您的代码更简单。您的上述代码可以替换为:

/* vertex data comes from an array */
glEnableClientState(GL_VERTEX_ARRAY);

/* we want to use a common color for all vertices */
glDisableClientState(GL_COLOR_ARRAY); 
glColor3f(1.0, 0.0, 0.0);

/* where to get the data from */
glVertexPointer(2, GL_DOUBLE, sizeof(double)*4, arr);

/* draw the whole thing */
glDrawArrays(GL_LINE_STRIP, 0, z);

/* cleanup */
glDisableClientState(GL_VERTEX_ARRAY);

正如您所看到的那样,它更短,更简洁,更易于阅读,并且避免执行z+3函数调用,每个调用都需要一些时间来执行。

重要,OpenGL可以消化多维数组arr是由于多维数组的静态分配存储始终是连续的。如果你为数组分配一个指针数组(动态分配多维数组的天真方式),它将无法工作。