Рендеринг кривых B-сплайна в OpenGL

Я работаю над проектом OpenGL, который по сути является практикой рисования кривых b-сплайна. Моя программа не возвращает ошибок, но кривые не отображаются.

Учитывая массив контрольных точек длиной 13 с именем «координаты» (сами контрольные точки видны на экране), это мой код:

glBegin(GL_LINE_STRIP);

float x=0;
float y=0;
float z=0;
for (double u = 3; u <= 14; u+=0.1){

    for (int i = 1; i <=13; i++){
        x += NofU(u,i)*coords[i].x;
        y += NofU(u,i)*coords[i].y;
        z += NofU(u,i)*coords[i].z;
    }//for

}//for

glVertex3f(x, y, z);

glEnd();

Где «NofU» представляет функции смешивания:

double NofU(double u, int i){

if (u < i)
    return 0;
else if (u < i+1)
    return (1/6)*pow(u,3);
else if (u < i+2)
    return (1/6)*((-3)*pow(u,3)+3*pow(u,2)+3*u+1);
else if (u < i+3)
    return (1/6)*(3*pow(u,3)-6*pow(u,2)+4);
else if (u < i+4)
    return (1/6)*pow((1-u),3);
else
    return 0;

}//NofU

Когда я пытаюсь вывести операторы печати, я получаю либо безумно большие, либо маленькие значения координат, либо просто 0.


person JMcMinn    schedule 17.11.2012    source источник


Ответы (2)


У вас есть только один вызов glVertex3f внутри блока glBegin/End. Итак, вы пытаетесь нарисовать линейную полосу только с одной точкой, что на самом деле невозможно. (Не уверен, действительно ли OpenGL сообщит об ошибке для этого или нет.)

Надеюсь это поможет.

person Hugh    schedule 19.11.2012
comment
Да, как оказалось, это было довольно глупо с моей стороны. Я переместил вершину внутрь петель, и теперь она вроде как работает. У меня сейчас другая проблема, но придется подождать другого вопроса. Спасибо за ответ. - person JMcMinn; 20.11.2012

Я бы также проверил вашу функцию расчета B-сплайнов. В моей ссылке (Advanced Animation and Rendering Techniques, Watt & Watt) есть два значения u. В верхнем регистре есть глобальное U, которое находится в диапазоне от 0 .. n до 2. Это соответствует вашему нижнему регистру u. Но для базовых функций (нижний регистр) u должен быть в диапазоне 0 .. 1. В вашем коде это будет fmod(u, 1). Я думаю, что если вы используете это во всех операторах возврата NoFu, вы получите лучшие ответы.

person Hugh    schedule 20.11.2012
comment
Спасибо за это; мой код претерпел некоторые изменения с тех пор, как я опубликовал этот вопрос, и теперь мой формат более точно соответствует тому, который вы упомянули. - person JMcMinn; 21.11.2012