Рисование римской поверхности Штейнера в OpenGL - PullRequest
1 голос
/ 14 октября 2011

Я пытаюсь нарисовать римскую поверхность Штейнера в OpenGL, и у меня возникают проблемы с получением правильных нормалей, чтобы поверхность правильно освещалась. Я использовал параметрическое уравнение из Википедии: http://en.wikipedia.org/wiki/Roman_surface. Для нормалей я сделал частичное дифференцирование по тэте, затем по фи, затем пересекли частные дифференциалы, чтобы получить нормаль.

Это не позволяет поверхности правильно освещаться, потому что римская поверхность - неориентируемая поверхность. Поэтому мне было интересно, есть ли способ вывести правильные нормали, чтобы поверхность могла правильно освещаться. Я пытался отрицать нормали для всей поверхности и части поверхности (отрицая для 1-й и последней четверти n), но, похоже, это не сработало.

Мой текущий код выглядит следующим образом:

double getRad(double deg, double n){
    return deg * M_PI / n;
}

int n = 24;

for(int i = 0; i < n; i++){
    for(int j = 0; j < 2*n; j++){

            glBegin(GL_POLYGON);

                double x = -pow(r,4) * cos(2*getRad(i+0.5,n)) * pow(cos(getRad(j+0.5,n)),2) * cos(2*getRad(j+0.5,n)) * sin(getRad(i+0.5,n)) - 2 * pow(r,4) * pow(cos(getRad(i+0.5,n)),2) * pow(cos(getRad(j+0.5,n)),2) * sin(getRad(i+0.5,n)) * pow(sin(getRad(j+0.5,n)),2);
                double y = pow(r,4) * cos(getRad(i+0.5,n)) * cos(2*getRad(i+0.5,n)) * pow(cos(getRad(j+0.5,n)),2) * cos(2*getRad(j+0.5,n)) - 2 * pow(r,4) * cos(getRad(i+0.5,n)) * pow(cos(getRad(j+0.5,n)),2) * pow(sin(getRad(i+0.5,n)),2) * pow(sin(getRad(j+0.5,n)),2);
                double z = -pow(r,4) * pow(cos(getRad(i+0.5,n)),2) * cos(getRad(j+0.5,n)) * cos(2*getRad(j+0.5,n)) * sin(getRad(j+0.5,n)) - pow(r,4) * cos(getRad(j+0.5,n)) * cos(2*getRad(j+0.5,n)) * pow(sin(getRad(i+0.5,n)),2) * sin(getRad(j+0.5,n));



                glNormal3d(x, y, z);                
                glVertex3d(r*r*cos(getRad(i,n))*cos(getRad(j,n))*sin(getRad(j,n)),r*r*sin(getRad(i,n))*cos(getRad(j,n))*sin(getRad(j,n)),r*r*cos(getRad(i,n))*sin(getRad(i,n))*cos(getRad(j,n))*cos(getRad(j,n)));
                glVertex3d(r*r*cos(getRad(i+1,n))*cos(getRad(j,n))*sin(getRad(j,n)),r*r*sin(getRad(i+1,n))*cos(getRad(j,n))*sin(getRad(j,n)),r*r*cos(getRad(i+1,n))*sin(getRad(i+1,n))*cos(getRad(j,n))*cos(getRad(j,n)));
                glVertex3d(r*r*cos(getRad(i+1,n))*cos(getRad(j+1,n))*sin(getRad(j+1,n)),r*r*sin(getRad(i+1,n))*cos(getRad(j+1,n))*sin(getRad(j+1,n)),r*r*cos(getRad(i+1,n))*sin(getRad(i+1,n))*cos(getRad(j+1,n))*cos(getRad(j+1,n)));
                glVertex3d(r*r*cos(getRad(i,n))*cos(getRad(j+1,n))*sin(getRad(j+1,n)),r*r*sin(getRad(i,n))*cos(getRad(j+1,n))*sin(getRad(j+1,n)),r*r*cos(getRad(i,n))*sin(getRad(i,n))*cos(getRad(j+1,n))*cos(getRad(j+1,n)));
            glEnd();

            glFlush();

    }
}

Ответы [ 3 ]

2 голосов
/ 14 октября 2011

В случае, если вы имеете дело с неориентируемыми поверхностями (например, римлянами Штейнера или знаменитой полосой Мёбиуса), у вас есть возможности: включить двустороннее освещение

glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);

или вы включаете выборку лица и визуализируете поверхность двумя проходами (лицевой и обратной стороной) - вам придется отрицать нормали для прохода задней стороны.

glEnable(GL_CULL_FACE);
glCullFace(GL_BACK); // backside faces are NOT rendered
draw_with_positive_normals();
glCullFace(GL_FRONT);
draw_with_negative_normals();
0 голосов
/ 14 октября 2011

Вы, вероятно, получите лучшие результаты, разделив многоугольник на два треугольника - каждый из них будет гарантированно плоским.Кроме того, вы можете сгенерировать нормали из каждого треугольника или сгладить их между соседними треугольниками.

Другая хитрость заключается в том, чтобы предварительно сгенерировать ваши точки в массив и затем ссылаться на массив в вызове glVertex.Таким образом, у вас будет больше возможностей для генерации нормалей.

Также вы можете визуализировать сами нормали с помощью последовательности glBegin (GL_LINES) ... glEnd ().

0 голосов
/ 14 октября 2011

Для каждого сгенерированного вами треугольника создайте его с такими же координатами / нормалями, но переверните / переверните другим способом.

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