Как нарисовать заполненный конверт как конус на OpenGL (используя GLUT)? - PullRequest
4 голосов
/ 26 октября 2008

Я использую freeglut для рендеринга opengl ...

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

Оснащен ли инструментарий freeglut такой встроенной функциональностью для рисования заполненных геометрий (или какой-то хитрости)? или есть какой-то другой API, который имеет встроенную поддержку для заполненных геометрий ..

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

и glutSolidCone мне не помогает, так как я хочу нарисовать заполненный сектор круга ... что я уже сделал ... что осталось сделать, это заполнить его некоторым цветом ... как заполнить геометрию цветом в opengl?

Edit2: Все ответы на эти вопросы могут работать для моей проблемы в некотором роде. Но я бы определенно хотел узнать, как заполнить геометрию каким-нибудь цветом. Скажем, если я хочу нарисовать конверт, который является параболой ... в этом случае не было бы никакой функции перенасыщения по умолчанию для рисования заполненной параболы (или есть ли такая?) .. Итак, чтобы обобщить этот вопрос ... как нарисовать пользовательскую геометрию в один сплошной цвет?

Edit3: Ответ, который разместил mstrobl, работает для GL_TRIANGLES, но для такого кода:

glBegin(GL_LINE_STRIP);

glColor3f(0.0, 0.0, 1.0);
    glVertex3f(0.0, 0.0, 0.0);
glColor3f(0.0, 0.0, 1.0);
    glVertex3f(200.0, 0.0, 0.0);
glColor3f(0.0, 0.0, 1.0);
    glVertex3f(200.0, 200.0, 0.0);
glColor3f(0.0, 0.0, 1.0);
    glVertex3f(0.0, 200.0, 0.0);
glColor3f(0.0, 0.0, 1.0);
    glVertex3f(0.0, 0.0, 0.0);

glEnd();

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

все равно сделать это?

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

Я не знаю, как это возможно для GL_TRIANGLES ... но как это сделать для любой замкнутой кривой?

Ответы [ 5 ]

2 голосов
/ 29 октября 2008

В Edit3: как я понимаю, ваш вопрос заключается в том, что вы хотите, чтобы OpenGL рисовал границы, а все, что между ними должно быть заполнено цветами.

Идея, которая у вас была, была правильной, но линейная полоса - это полоса линий, и у нее нет никакой области.

Однако вы можете соединить линии друг с другом, чтобы определить многоугольник. Это заполнит область многоугольника для каждой вершины. Адаптация вашего кода:

glBegin(GL_POLYGON);

glColor3f(0.0, 0.0, 1.0);
    glVertex3f(0.0, 0.0, 0.0);
glColor3f(0.0, 0.0, 1.0);
    glVertex3f(200.0, 0.0, 0.0);
glColor3f(0.0, 0.0, 1.0);
    glVertex3f(200.0, 200.0, 0.0);
glColor3f(0.0, 0.0, 1.0);
    glVertex3f(0.0, 200.0, 0.0);
glColor3f(0.0, 0.0, 1.0);
    glVertex3f(0.0, 0.0, 0.0);

glEnd();

Обратите внимание, однако, что рисование полигона таким образом имеет два ограничения:

  • Многоугольник должен быть выпуклым.
  • Это медленная операция.

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

2 голосов
/ 28 октября 2008

На редактирование по цветам:

OpenGL на самом деле является конечным автоматом. Это означает, что при рисовании используется текущая позиция материала и / или цвета. Поскольку вы, вероятно, не будете использовать материалы, игнорируйте это сейчас. Вы хотите цвета.

glColor3f(float r, float g, float b) // draw with r/g/b color and alpha of 1
glColor4f(float r, float g, float b, float alpha)

Это повлияет на цвета любых вершин, которые вы рисуете, любой геометрии, которую вы визуализируете - будь то глю или ваша собственная - после того, как вызов glColorXX был выполнен. Если вы рисуете грань с вершинами и меняете цвет между вызовами glVertex3f / glVertex2f, цвета интерполируются.

Попробуйте это:

glBegin(GL_TRIANGLES);
glColor3f(0.0, 0.0, 1.0);
glVertex3f(-3.0, 0.0, 0.0);
glColor3f(0.0, 1.0, 0.0);
glVertex3f(0.0, 3.0, 0.0);
glColor3f(1.0, 0.0, 0.0);
glVertex3f(3.0, 0.0, 0.0);
glEnd();

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

Так же, как вы можете отображать списки вершин, вы также можете сделать так, чтобы у них был список цветов: все, что вам нужно сделать, это включить списки цветов и сообщить opengl, где находится список. Конечно, они должны иметь такой же наряд, как и список вершин (в том же порядке).

Если бы у вас было

glEnableClientState(GL_VERTEX_ARRAY);   
glVertexPointer(3, GL_FLOAT, 0, vertices_);
glDisableClientState(GL_VERTEX_ARRAY);

Вы должны добавить цвета таким образом. Они не должны быть плавающими; на самом деле, вы говорите, в каком формате это должно быть. Для списка цветов с 1 байтом на канал и 4 каналами (R, G, B и A) используйте это:

glEnableClientState(GL_VERTEX_ARRAY);   
glEnableClientState(GL_COLOR_ARRAY);
glVertexPointer(3, GL_FLOAT, 0, vertices_);
glColorPointer(4, GL_UNSIGNED_BYTE, 0, colors_);
glDisableClientState(GL_COLOR_ARRAY);
glDisableClientState(GL_VERTEX_ARRAY);

EDIT: забыл добавить, что вы должны сообщить OpenGL, какие элементы рисовать, вызвав glDrawElements .

2 голосов
/ 26 октября 2008

Я помню, что для этого была подпрограмма. Но это не так уж сложно сделать самостоятельно.

Но я не понимаю, что такое 2D. Конус в 2D? Разве это не просто треугольник?

В любом случае, вот алгоритм рисования конуса в opengl

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

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

Сначала просто подразделите скалярное значение. Начните с [0-2] -диапазона. Возьмите среднюю точку ((начало + конец) / 2) и разделите диапазон с ней. Храните значения в виде пар. Например, подразделение один раз должно дать вам: [(0,1), (1,2)] Сделайте это рекурсивно пару раз, затем вычислите, что это за точки на окружности. Простая тригонометрия, просто не забудьте умножить значения на π, прежде чем продолжить. После этого у вас есть определенное количество ребер. 2 ^ n, где n - количество подразделений. Затем вы можете просто превратить их в треугольники, дав им еще одну точку вершины. Таким образом, количество треугольников получается равным: 2 ^ (n + 1). (Суммы полезно знать, если вы делаете это с массивами фиксированного размера.

Редактировать: То, что вы действительно хотите, это пирог. (Извините за каламбур)

Рендеринг одинаково прост. Вы можете снова использовать только треугольники. Просто выберите скалярный диапазон [-0,25 - 0,25], разделите, спроецируйте на окружность и сгенерируйте один набор треугольников.

Проекция скалярной окружности проста: x = cos (v * pi) r, y = sin (v pi) * r, где (x, y) - результирующая точка вершины, r является радиусом, а тригонометрические функции работают с радианами, а не градусами. (если они работают с градусами, замените пи на 180)

Используйте буферы вершин или списки, чтобы визуализировать их самостоятельно.

Редактировать: О вопросе раскраски. glColor4f, если вы хотите, чтобы некоторые части геометрии отличались по цвету, вы можете назначить цвет для каждой вершины в самом буфере вершин. Сейчас я не знаю всех вызовов API, чтобы сделать это, но ссылка на API в opengl вполне понятна.

2 голосов
/ 27 октября 2008

Поскольку вы уточнили свой вопрос, чтобы попросить пирог: есть простой способ нарисовать его, используя примитивы opengl:

Вы бы нарисовали сплошную сферу, используя gluSolidSphere (). Однако, поскольку вы хотите нарисовать только его часть, вы просто отсекаете ненужные части:

void glClipPlane(GLenum plane, const GLdouble * equation);

С плоскостью от GL_CLIPPLANE0 до GL_CLIPPLANEn и уравнением, являющимся уравнением плоскости в нормальной форме (a x + b y + c * z + d = 0 будет означать, что уравнение будет содержать значения { a, b, c, d }. Пожалуйста, обратите внимание, что это двойные числа, а не числа с плавающей точкой.

2 голосов
/ 26 октября 2008

Я не уверен, что вы подразумеваете под "конвертом", но конус - это примитив, который имеет избыток:

glutSolidCone(radius, height, number_of_slices, number_of_stacks)

Самый простой способ закрасить его цветом - нарисовать его цветом. Поскольку вы хотите сделать его несколько прозрачным, вам также нужно альфа-значение:

glColor4f(float red, float green, float blue, float alpha)
// rgb and alpha run from 0.0f to 1.0f; in the example here alpha of 1.0 will
// mean no transparency, 0.0 total transparency. Call before drawing.

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

glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

Вызовите это перед выполнением любых операций рисования, возможно, при инициализации программы. :)

...