Как нарисовать спираль, используя OpenGL - PullRequest
8 голосов
/ 14 декабря 2009

Я хочу знать, как нарисовать спираль.

Я написал этот код:

void RenderScene(void)
{
    glClear(GL_COLOR_BUFFER_BIT);
    GLfloat x,y,z = -50,angle;
    glBegin(GL_POINTS);

    for(angle = 0; angle < 360; angle += 1)
    {   
        x = 50 * cos(angle);
        y = 50 * sin(angle);
        glVertex3f(x,y,z);
        z+=1;
    }
    glEnd();
    glutSwapBuffers();
}

Если я не включаю термины z, я получаю идеальный круг, но когда я включаю z, тогда я получаю 3 точки. Что могло случиться?

Я установил область просмотра, используя glviewport (0,0, w, h)

Чтобы включить z, я должен сделать что-нибудь, чтобы установить область просмотра в направлении z?

Ответы [ 3 ]

14 голосов
/ 14 декабря 2009

Вы видите точки, потому что рисуете точки с помощью glBegin(GL_POINTS). Попробуйте заменить его на glBegin(GL_LINE_STRIP).

ПРИМЕЧАНИЕ: когда вы видели круг, вы также рисовали только точки, но при этом они были нарисованы достаточно близко, чтобы отображаться в виде связного круга.

Кроме того, возможно, вы не настроили буфер глубины для приема значений в диапазоне z = [-50, 310], который вы используете. Эти аргументы должны быть представлены в виде zNear и zFar плоскостей отсечения в вашем вызове gluPerspective, glOrtho() или glFrustum().

ПРИМЕЧАНИЕ: это объясняет, почему при значении z вы видите только несколько точек: остальные точки обрезаются, потому что они находятся вне диапазона z-буфера.

ОБНОВЛЕНИЕ ПОСЛЕ ТОГО, КАК ВЫ УКАЗАЛЕ свой КОД:

glOrtho(-100*aspectratio,100*aspectratio,-100,100,1,-1); допускает только z-значения в диапазоне [-1, 1], поэтому будут нарисованы только три точки с z = -1, z = 0 и z = 1 (таким образом, 3 точки).

Наконец, вы, вероятно, смотрите на спираль сверху, глядя прямо в направлении оси вращения. Если вы не используете перспективную проекцию (но изометрическую), спираль все равно будет отображаться в виде круга. Возможно, вы захотите изменить свой взгляд с помощью gluLookAt().

ПРИМЕР НАСТРОЙКИ ПЕРСПЕКТИВНЫЙ

Следующий код взят из отличных руководств по OpenGL от NeHe:

glViewport(0, 0, width, height);
glMatrixMode(GL_PROJECTION);                        // Select The Projection Matrix
glLoadIdentity();                           // Reset The Projection Matrix

// Calculate The Aspect Ratio Of The Window
gluPerspective(45.0f,(GLfloat)width/(GLfloat)height,0.1f,100.0f);

glMatrixMode(GL_MODELVIEW);                     // Select The Modelview Matrix
glLoadIdentity();                           // Reset The Modelview Matrix

Тогда в вашем цикле рисования будет выглядеть примерно так:

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);     // Clear The Screen And The Depth Buffer
glLoadIdentity();   
glTranslatef(-1.5f,0.0f,-6.0f);                 // Move Left 1.5 Units And Into The Screen 6.0
glBegin(GL_TRIANGLES);                      // Drawing Using Triangles
    glVertex3f( 0.0f, 1.0f, 0.0f);              // Top
    glVertex3f(-1.0f,-1.0f, 0.0f);              // Bottom Left
    glVertex3f( 1.0f,-1.0f, 0.0f);              // Bottom Right
glEnd();    

Конечно, вы должны изменить этот пример кода для своих нужд.

1 голос
/ 19 сентября 2013

Вот моя функция Spiral в C. Точки сохраняются в список, который может быть легко нарисован OpenGL (например, соединить смежные точки в списке с помощью GL_LINES).

  • cx, cy ... спиральные координаты x и y центра
  • r ... максимальный радиус спирали
  • num_segments ... количество сегментов, которое будет иметь спираль

    SOME_LIST* UniformSpiralPoints(float cx, float cy, float r, int num_segments)
    {
    SOME_LIST *sl = newSomeList();
    int i;
    
    for(i = 0; i < num_segments; i++)
    {
    float theta = 2.0f * 3.1415926f * i / num_segments; //the current angle
    
    float x = (r/num_segments)*i * cosf(theta); //the x component
    float y = (r/num_segments)*i * sinf(theta); //the y component
    
    //add (x + cx, y + cy) to list sl
    
    }
    return sl; 
    }
    

Пример изображения с r = 1, num_segments = 1024:

enter image description here

P.S. Существует разница в использовании cos (double) и cosf (float). Вы используете переменную типа float для двойной функции cos.

1 голос
/ 26 февраля 2013

catchmeifyoutry предоставляет совершенно функциональный метод, но не будет рисовать пространственно точную трехмерную спираль, так как любой вызов рендеринга, использующий примитивный тип GL_LINE, растеризуется до фиксированной ширины пикселя. Это означает, что при изменении перспективы / вида линии не будут менять ширину. Для этого используйте геометрический шейдер в сочетании с GL_LINE_STRIP_ADJACENCY для создания трехмерной геометрии, которую можно растеризовать, как и любую другую трехмерную геометрию. (Однако для этого требуется использовать конвейер с фиксированной функцией после публикации)

Я рекомендовал вам сначала попробовать метод catchmeifyoutry, так как он будет намного проще. Если вы не удовлетворены, попробуйте метод, который я описал. Вы можете использовать следующий пост в качестве руководства:

http://prideout.net/blog/?tag=opengl-tron

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...