1

私は週末のプロジェクトである基本的な OpenGl プログラムを作成しています。
説明: ウィンドウ画面でマウスをドラッグすると、ボタン (左) を放した後、マウスをドラッグしたパスを示す線が表示され、円がその線を最初から最後まで横切る必要があります。
私のコードは非常にうまく機能しますが、問題は、描画された線が連続していない[むしろ破線である]ことであり、OS画面からOpenGL画面へのマッピングが原因である可能性があります。SOは、連続した行パスを作成するか、私を修正する方法はありますか?何か間違ったことをしている場合、これ
が私のコードです:

#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連続する 2 つの頂点が線分を構成する描画モードです。それから次の2つなど。あなたが描いているのはラインストリップです。に置き換える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 に答える