Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Мультимедия, OpenGL/DirectX > OpenGL: как нарисовать сглаженную окружность?


Автор: kamre 25.5.2008, 16:00
Пытаюсь нарисовать окружности через OpenGL. Сейчас код выглядит примерно вот так:
Код

glLineWidth(2.0);
...
enum { n = 256 };
glClear(GL_COLOR_BUFFER_BIT);
glBegin(GL_LINE_LOOP);
for (int i = 0; i < n; i++) {
  double angle = 2*pi*i/n;
  glVertex2f(r*cos(angle), r*sin(angle));
}
glEnd();


Окружность рисуется, но линии не сглаженные получаются. Хочу добиться отрисовки почти как в Qt (слева):
user posted image
Как это можно сделать в OpenGL?

Если добавляю сразу после glLineWidth(2.0) еще и glEnable(GL_LINE_SMOOTH), то вообще получается фигня:
user posted image

Автор: bronislav 27.5.2008, 14:32
Код

glEnable(GL_SMOOTH);

Автор: kamre 29.5.2008, 09:47
Цитата(bronislav @ 27.5.2008,  14:32)
Код

glEnable(GL_SMOOTH);

К сожалению, это ничего не дает. Если только это написать, то как в первом рисунке. Если добавить еще glEnable(GL_LINE_SMOOTH), то как на втором. 

Это я все на работе запускаю, видео у меня GeForce 2 MX 400. Может быть из-за видеокарты не сглаживает? Дома на ноутбуке, кажется, видео intel G945. Там тоже самое. Может кто-нибудь показать, как это в сглаженном виде выглядит?

Еще нашел пример из qtdemo, Sample Buffer, но он не запускается. Пишет, что система не поддерживает sample buffer. Через sample buffer тоже можно сглаживать?

Автор: Shuravi 10.7.2008, 04:36
рисуя примитивы, как менять цвет линий, не затрагивая при этом цвет заливки?

Автор: mes 10.7.2008, 17:36
Цитата(kamre @  25.5.2008,  16:00 Найти цитируемый пост)
Окружность рисуется, но линии не сглаженные получаются.

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

Добавлено через 4 минуты и 45 секунд
Цитата(Shuravi @  10.7.2008,  04:36 Найти цитируемый пост)
рисуя примитивы, как менять цвет линий, не затрагивая при этом цвет заливки? 

в опенгл? выбрать цвет, нарисовать заливку фигуры, поменять цвет и нарисовать линии. 
в Qt (wxWidgets, WinApi и т.д)  для рисования заливки используется кисть (..Brush) , а для контура Карандаш (..Pen)   smile

Добавлено через 8 минут и 41 секунду
Цитата(kamre @  25.5.2008,  16:00 Найти цитируемый пост)
glVertex2f(r*cos(angle), r*sin(angle));

попробуй посмотреть тут : http://alglib.sources.ru/graphics/  smile 

Автор: Quartz 15.7.2008, 00:10
Цитата

Код

glEnable(GL_SMOOTH);

К сожалению, это ничего не дает. Если только это написать, то как в первом рисунке. Если добавить еще glEnable(GL_LINE_SMOOTH), то как на втором. 

Как-то так должно быть  smile :
Код
glShadeModel( GL_SMOOTH );
glEnable( GL_ALPHA_TEST );
glEnable(GL_BLEND);
glEnable(GL_LINE_SMOOTH);

Автор: Supersedes 29.7.2008, 08:43
Привет. Все что тебе надо, это включить прозрачность при помощи glEnable( GL_BLEND ); и glBlendFunc(...);
Вот кусок моего кода:

Код

void render( void )
{
    int    i;
    float    a;

    glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );

    glLineWidth( 2.0f );

    glHint( GL_LINE_SMOOTH_HINT, GL_NICEST );
    glEnable( GL_LINE_SMOOTH );

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

    glClear( GL_COLOR_BUFFER_BIT );
    glBegin( GL_LINE_LOOP );
    for ( i = 0; i < 50; i++ ) {
        a = (float)i / 50.0f * 3.1415f * 2.0f;
        glVertex2f( cos( a ) * 5.0f, sin( a ) * 5.0f );
    }
    glEnd();

    glFlush();
    SwapBuffers( g_hDC );
}

Автор: Rickert 30.7.2008, 04:01
Shuravi, рисовать сначала полигоны одним цветом, потом менять его и рисовать линии.
Supersedes, При чём тут смешивание?
Этот эффект называется antialising.
А если смотреть стандартные средства и почитать перевод красной книги OpenGL на progz.ru, то найдёте вот это - http://www.progz.ru/articles.php?view=56 - пункт 6.2
И ещё вот это - http://www.progz.ru/articles.php?view=52 - пункт 10.3.1

Автор: kamre 30.7.2008, 09:57
Цитата(Supersedes @ 29.7.2008,  08:43)
Привет. Все что тебе надо, это включить прозрачность при помощи glEnable( GL_BLEND ); и glBlendFunc(...);
Вот кусок моего кода:

Код

void render( void )
{
    ...
    glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );

    glLineWidth( 2.0f );

    glHint( GL_LINE_SMOOTH_HINT, GL_NICEST );
    glEnable( GL_LINE_SMOOTH );

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


Спасибо огромное!!
Добавил в инициализацию эти строки, сейчас вот так рисуется:
user posted image
Буду разбираться, как это оно так работает smile

Автор: Rickert 31.7.2008, 04:54
Тут скорее     "glHint( GL_LINE_SMOOTH_HINT, GL_NICEST );", а не смешивание виновато.

Автор: kamre 31.7.2008, 13:46
Цитата(Rickert @ 31.7.2008,  04:54)
Тут скорее     "glHint( GL_LINE_SMOOTH_HINT, GL_NICEST );", а не смешивание виновато.

Если убрать вот эти строки:
Код

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

то получится вот так:
user posted image

Кстати, а почему при использовании blending на разных компьютерах (видеокартах/платформах) все начинает выглядеть по разному?
Дома на ноутбуке (intel 945G) в winXP все линии получились толще, а в линуксе (openSUSE 11.0) все гораздо тоньше?
Еще в линуксе размеры сглаженных точек не меняются почему-то... 

Это такая разная (кривая?) поддержка OpenGL в драйверах или я что-то не так делаю?
Если действительно поддержка OpenGL такая разная, то как тогда можно написать приложение, чтобы оно везде одинаково отрисовывало объекты?

Автор: Supersedes 4.8.2008, 11:24
Цитата

Supersedes, При чём тут смешивание?
Этот эффект называется antialising.


При том, что Antialiasing линий добивается при помощи прозрачности или как ты говоришь смешивании!

Цитата

Тут скорее     "glHint( GL_LINE_SMOOTH_HINT, GL_NICEST );", а не смешивание виновато.


Нет, тут скорее всего виноваты те, кто ничего толком не знает и тем не менее пытается что-то доказать. Например такие как ты.

Проверь. Это работает. Факт остается фактом.

Автор: Rickert 4.8.2008, 12:05
Цитата(Supersedes @  4.8.2008,  11:24 Найти цитируемый пост)
При том, что Antialiasing линий добивается при помощи прозрачности или как ты говоришь смешивании!

Понятия прозрачности впринципе не существует в OpenGL.
Есть понятие "смешивания". Даже то что ты делаешь glEnable(GL_BLEND) - blend - смешивать.
Попробуйзадать макимальную непрозраночсть через тот же glColor4ub - у тебя всё равно объект будет прозрачным.

Цитата(Supersedes @  4.8.2008,  11:24 Найти цитируемый пост)
Нет, тут скорее всего виноваты те, кто ничего толком не знает и тем не менее пытается что-то доказать. Например такие как ты.

Проверь. Это работает. Факт остается фактом. 

Вообщем-то и какаху можно зашвырнуть, а потом крикнуть: смотри - "оно" умеет летать.

Вы сами не понимаете что пишите, а просто тыкаете. Об этом свидетельствует хотя бы одно то, что вот эти строки вы запихали при рендеринге каждого кадра, а не при инициализации:
Код
glHint( GL_LINE_SMOOTH_HINT, GL_NICEST );
glEnable( GL_LINE_SMOOTH );
glEnable( GL_BLEND );
glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );


А теперь, дорогой мой, расскажите мне что значит каждая из этих строк.
Понимаешь, иногда делаешь и вроде работает правильно, а потом когда глубже копнёшь - понимаешь, что написанное реализует совсем другую задачу и сходство лишь внешне.

Автор: Supersedes 4.8.2008, 12:25
Цитата

Попробуйзадать макимальную непрозраночсть через тот же glColor4ub - у тебя всё равно объект будет прозрачным.

Ээээ... Это вообще к чему?

Цитата

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

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

Цитата

Вообщем-то и какаху можно зашвырнуть, а потом крикнуть: смотри - "оно" умеет летать.

Можно. И оно действительно будет летать если кидать будет то кто знает, а не догадывается.

Цитата

А теперь, дорогой мой, расскажите мне что значит каждая из этих строк.

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

Цитата

Понимаешь, иногда делаешь и вроде работает правильно, а потом когда глубже копнёшь - понимаешь, что написанное реализует совсем другую задачу и сходство лишь внешне.

Если ты можешь привести код, который будет в данном случае правильней и проще моего, то я действительно буду приятно удивлен твоими познаниями. Я так понял этим ты хотел сказать то, что я написал сам не знаю что??!

Автор: kamre 5.8.2008, 22:40
Вот вы мне лучше подскажите, почему так по разному отображается все через opengl.
WinXP + Geforce MX400:
user posted image
WinXP + Intel 945G:
user posted image
openSUSE 11.0 + Intel 945G:
user posted image

Хотя код для инициализации один и тот же:
Код

  void initializeGL() {
    qglClearColor(Qt::darkGray);
    qglColor(Qt::white);
    glLineWidth(2.0);
    glHint(GL_LINE_SMOOTH_HINT, GL_NICEST);
    glEnable(GL_LINE_SMOOTH);
    glEnable(GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  }

Как при таком различии можно что-то аккуратно отобразить с помощью opengl? Что же я не так делаю все-таки?

Автор: Supersedes 6.8.2008, 08:04
Т.к. в openSUSE 11.0 ниразу не работал, то могу предположить что OpenGL неккоректно работает с Intel 945G, ведь как я вижу с Geforce MX400 все работает нормально. Баги разные бывают.. Возможно Qt учитывает именно этот недостаток видеокарты и исправляет его каким-то образом. К сожалению на этот вопрос я не могу дать тебе конкретного объяснения... Увы..

Кстати, ты не пробовал на время испытаний отключать Qt (например закоментировать все строки инициализации и т.п.) !!? У меня есть подозрения что это может быть причиной неправильной работы.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)