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;
}


这就是我得到的:

我的代码输出

4

1 回答 1

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_LINESGL_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是因为多维数组的静态分配存储始终是连续的。如果您分配一个指向数组的指针数组(动态分配多维数组的天真方法),它将不起作用。

于 2013-10-27T12:51:52.780 回答