2013-10-27 121 views
1

我正在做一個基本的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

回答

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_LINE_STRIP代替GL_LINES會給你預期的結果。

在旁註:您應該放棄使用即時模式(glBegin,glVertex,glEnd)。它速度很慢,工作起來很麻煩,並且從長遠來看可以成爲主要的PITA。至少使用頂點數組;他們一直是提供幾十年以上的幾何數據的推薦方式。另外它使你的代碼更簡單。你上面的代碼可以用這個來代替:

/* 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是由於這樣的事實,即靜態分配多維數組的存儲總是鄰接的。如果你要爲數組分配一個指針數組(這是動態分配多維數組的單調方式),那麼這將不起作用。

+0

謝謝你的答案和關於使用頂點數組的一個非常好的信息。 這工作像魅力 – adil

+0

我還有一個問題。當我使用上面的代碼的exe文件在我的朋友pc上,而不是一個圓形的點時,有一個方形的盒子在遍歷路徑。 這可能是什麼原因? – adil

+0

@adil:通常情況下,您會得到點平滑的平方點被禁用,並且啓用點平滑的圓點。我沒有看到您的程序啓用點平滑。然而,實現在解釋點的過程中有一些餘地(我建議閱讀關於該主題的規範),並且您的朋友可能在驅動程序中啓用了抗鋸齒功能,這使得該點顯得圓滑。 – datenwolf