Реализация полноэкранного сглаживания методом мультисэмплинга в OpenGL

Авторы: 
Борис Михайлович
Авторы: 
Антон Конушин
Один из способов улучшения качества синтезированного изображения является полноэкранное сглаживание или "устранение ступенчатости" (anti-aliasing), подавляющей "лестничный эффект" (aliasing). Благодаря бурному развитию аппаратных ускорителей 3-х мерной визуализации этот метод стал широко использоваться в системах интерактивной визуализации. В этой статье на небольшом примере будет рассмотрена реализация полноэкранного сглаживания с использованием библиотеки OpenGL. Описанный способ будет работать на большинстве современных ускорителей, производства как фирмы NVIDIA, так и ATI.

Скачать пример программы (.rar, 151k)

Один из способов улучшения качества синтезированного изображения является полноэкранное сглаживание или <устранение ступенчатости> (anti-aliasing), подавляющей <лестничный эффект> (aliasing). Благодаря бурному развитию аппаратных ускорителей 3-х мерной визуализации этот метод стал широко использоваться в системах интерактивной визуализации. В этой статье на небольшом примере будет рассмотрена реализация полноэкранного сглаживания с использованием библиотеки OpenGL. Описанный способ будет работать на большинстве современных ускорителей, производства как фирмы NVIDIA, так и ATI.

Содержание

  1. Введение.
  2. Создание контекста OpenGL с поддержкой полноэкранного сглаживания.
    1. Создание контекста и работа с OpenGL при помощи GLRC.
    2. Создание контекста и работа с OpenGL с поддержкой полноэкранного сглаживания.
    3. Метод 1 - Повторное создание текущего окна.
    4. Метод 2 - Создание временного окна.
    5. Сравнение различных режимов полноэкранного сглаживания по методу мульти-сэмплинга
  3. Ссылки.

 

Введение

Лестничный эффект значительно снижает качество интерактивной визуализации. Особенно это заметно если сцена содержит большое количество тонких объектов и линий. Поэтому даже частичное устранение этого эффекта резко повышает общее качество визуализации и делает его более приятным для глаз, т.к. подавляется раздражающее <дрожание> пикселей.

Одним из самых эффективных способов его подавления является полноэкранное сглаживание. В современных графических ускорителях полноэкранное сглаживание реализуется методом мултисэмплирования (multi-sampling). В этом случае, внутри каждого пикселя вместо одной точки вычисляется сразу несколько, значения цветов которых смешиваются. Количество точек определяет режим мультисэмплирования. Сейчас многими ускорителями поддерживаются 2-х, 4-х и 6-и точечные режимы.

В этой статье описывается два способа включения поддержки полноэкранного сглаживания при работе с библиотекой OpenGL с использованием компонента UtilsGL из библиотеки GML.

Предложенный пример реализован под MVSC 6.0 c использованием библиотеки GMLib, а именно ее компонента UtilsGL версии 1.0.1. Для запуска приложения потребуется компьютер с операционной системой Windows ME, 2000 или XP с установленным графическим акселератором, поддерживающим полноэкранное сглаживание методом мульти-сэмплинга. (Например, ATI Radeon 9600,9700,9800 или GeForce FX ).

Для понимания примера необходимы базовые знания библиотек MFC и OpenGL.

Создание контекста OpenGL с поддержкой полноэкранного сглаживания

Компонент UtilsGL из библиотеки GML разработан специально для упрощения процедуры создания контекста OpenGL с требуемыми свойствами. Он состоит из:

  • Класса GLRC, отвечающего за создание и работу с контекстом OpenGL
  • Структуры sMultisampleModes, используемой для получения и работы с параметрами полноэкранного сглаживания. На данный момент поддерживается метод мульти-сэмплинга в режимах 2x, 4x, 6x

Создание контекста и работа с OpenGL при помощи GLRC

Обычную схему создания контекста OpenGL можно представить так:

Рис 1 Стандартная схема создания контекста OpenGL

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

Более детально сейчас будет рассмотрена схема создания контекста OpenGL с использованием gml::GLRC. До создания контекста необходимо создать окно и проверить полученное значение hWnd на корректность.

Функция Create из gml::GLRC создает стандартное окно с двойной буферизацией и обычными параметрами:


bool Create()
{
int nPixelFormat = 0;
DWORD flags;

flags = PFD_DRAW_TO_WINDOW | // Format Must Support Window
PFD_SUPPORT_OPENGL | // Format Must Support OpenGL
PFD_DOUBLEBUFFER; // Must Support Double Buffering

static PIXELFORMATDESCRIPTOR pfd =

{

sizeof (PIXELFORMATDESCRIPTOR), // Size Of This Pixel Format Descriptor
1, // Version Number
flags,
PFD_TYPE_RGBA, // Request An RGBA Format
24, // Select Our Color Depth
0, 0, 0, 0, 0, 0, // Color Bits Ignored
1, // Alpha Buffer
0, // Shift Bit Ignored
0, // No Accumulation Buffer
0, 0, 0, 0, // Accumulation Bits Ignored
32, // 16Bit Z-Buffer (Depth Buffer)
0, // No Stencil Buffer
0, // No Auxiliary Buffer
PFD_MAIN_PLANE, // Main Drawing Layer
0, // Reserved
0, 0, 0 // Layer Masks Ignored
};

pfd.cAlphaBits = 8;
nPixelFormat = ChoosePixelFormat( m_dc, &pfd ); // Выбираем Правильный формат пикселя

VERIFY( SetPixelFormat( m_dc, nPixelFormat, &pfd ) ); // Устанавливаем выбранный формат

m_glrc = wglCreateContext( m_dc ); // Создаем контекст

return MakeCurrent(); // Делаем его текущим

}

Таким образом, при использования gml::GLRC вся процедура создания окна записывается следующим образом:


// :

// Мы создали hWnd и проверили на правильность
// У нас определен член класса нашей программы Program
// gml::GLRC* m_rc;
// Которому при инициализации присваивается NULL
// Теперь надо его создать правильно

m_rc = new gml::GLRC( hWnd );

if( !m_rc->Create() )
{

// произошла ошибка про создании контекста -- обработать

}

// Теперь надо инициализировать OpenGL значениями и параметрами которые необходимы нам в дальнейшем

InitGL();


// После чего мы можем дальше работать с OpenGL как захотим

// ...


Для визуализации сцены в обработчике OnPaint необходимо сделать контекст текущим, отрисовать сцену, а затем вызвать SwepBuffers() для переключения буфера экрана и вывода изображения на экран.

void Program::OnPaint() 
{
m_rc->MakeCurrent();

// Работаем с OpenGL - наш Rendering Pipeline

m_rc->SwapBuffers();
}

Создание контекста и работа с OpenGL с поддержкой полноэкранного сглаживания

Главное отличие данной схемы от стандартной заключается в необходимости проверки контекста на возможность использования полноэкранного сглаживания в режиме мульти-сэмплинга. Для этого после создания контекста проверяется формат пикселя. Однако, по спецификации Microsoft функция SetPixelFormat() может быть вызвана только один раз для каждого окна (hWnd). Это было сделано для поддержки многопоточных приложений, но значительно затрудняет реализацию полноэкранного сглаживания.

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

Метод 1 - Повторное создание текущего окна

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


//:
// Создаем окно в два прохода

HWND hWnd = CreateWindowEx( /*:*/ )

if( hWnd == 0 )
{
// Ошибка
}

// Создаем экземпляр GLRC

m_rc = new gml::GLRC( hWnd );
if( m_sMultisampleModes. m_bMultisampleSupported )
{
// Создадим контекст с использованием полноэкранного сглаживания в режиме мульти-сэмплинга 4x
if(!m_rc->CreateMultisampled( m_bMultisampleSupported.SetMultisample4x() ) )
{
// Ошибка при создании контекста
}

}

if( !m_rc->Create() )
{
// Ошибка
}

// ...

// Теперь надо инициализировать и проверить возможность полноэкранного сглаживания
// Для этого необходим еще один член класса:
// sMultisampleModes m_sMultisampleModes;
// который используется для сохранения возможностей и pixel format-ов

// ...

// При первом заходе:

bool arbMultisampleSupported = m_rc->IsMultisampleSupported();

if( arbMultisampleSupported )
{
m_sMultisampleModes = m_rc->GetMultisampleModes();
// Теперь надо уничтожить и создать заново окно.
}
else
{
// Сглаживание не поддерживается, следовательно работаем без него
}

// ...
// При втором начинаем работу как обычно
// ...

Осталось только включить режим полноэкранного сглаживания

//На этапе либо инициализации включаем
//glEnable( GL_MULTISAMPLE_ARB );

// А потом выключаем с помощу glDisable();

// Либо динамически при необходимости
// (динамическое включение/выключение поддерживается не всеми видеокартами).

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

Таким образом, отключить полноэкранное сглаживание невозможно с помощью функции glDisable. Необходимо создать окно программы заново с отключенной поддержкой сглаживания с помощью функции GLRC::Create(), а не GLRC::CreateMultisampled().

Метод 2 - Создание временного окна

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


// Основное окно должно поддерживать полноэкранное сглаживание но ему необязательно входить в этот режим.
// Создадим временное окно, в котором ничего не будет рисоваться. Используем временное окно для получения структуры sMultisampleModes
// Для этого вызовем специальную функцию, внутри которой и создается временное окно. В
// качестве возвращаемого значения мы получаем структуру sMultisampleModes.

m_ sMultisampleModes = CheckForMultisample( /*:*/ );

// Переключаемся в режим полноэкранного сглаживания
// Заставляем главное окно перестроится, например, с помощью функции this->Rebuild()

this->Rebuild();

// Далее как и в методе 1

Сравнение различных режимов полноэкранного сглаживания по методу мульти-сэмплинга

<?xml:namespace prefix = v />

Без полноэкранного сглаживания

Полноэкранное сглаживание в режиме мульти-сэмплирования 2х

Полноэкранное сглаживание в режиме мульти-сэмплирования 4х

Полноэкранное сглаживание в режиме мульти-сэмплирования 6х

Ссылки

1. "OpenGL Multisample", GDC2002, http://developer.nvidia.com/object/gdc_ogl_multisample.html

2. http://nehe.gamedev.net/

Дополнительная информация
Ссылка: 
Борис Михайлович, Антон Конушин. Реализация полноэкранного сглаживания методом мультисэмплинга в OpenGL. Компьютерная графика и мультимедиа. Выпуск №2(2)/2004. http://cgm.computergraphics.ru/content/view/60
Выпуск: 
Выпуск №2(2)/2004

Комментарии

Отправить комментарий

Содержание этого поля является приватным и не предназначено к показу.
  • Адреса страниц и электронной почты автоматически преобразуются в ссылки.
  • Allowed HTML tags: <a> <em> <strong> <cite> <code> <ul> <ol> <li> <dl> <dt> <dd>
  • Строки и параграфы переносятся автоматически.

Подробнее о форматировании

CAPTCHA
Тест предназначен для отсеивания спама
Fill in the blank