Главная страница
Навигация по странице:

  • 9.1.2.

  • Руководство по работе с графической библиотекой OpenGL. Руководство разработано с учетом опыта чтения курса Компьютерная графика


    Скачать 0.66 Mb.
    НазваниеРуководство по работе с графической библиотекой OpenGL. Руководство разработано с учетом опыта чтения курса Компьютерная графика
    Дата21.10.2022
    Размер0.66 Mb.
    Формат файлаdocx
    Имя файла221937-83556.docx
    ТипРуководство
    #747097
    страница16 из 30
    1   ...   12   13   14   15   16   17   18   19   ...   30
    9.1.1. Высокоуровневая оптимизация

    Обычно от программы под OpenGL требуется визуализация высокого качества на интерактивных скоростях. Но как правило, и то и другое сразу получить не удается. Следовательно, необ­ходим поиск компромисса между качеством и производительно­стью. Существует множество различных подходов, но их подроб­ное описание выходит за пределы этого пособия. Приведем лишь несколько примеров.

    Можно отображать геометрию сцены с низким качеством во время анимации, а в моменты остановок показывать ее с

    115

    116

    Глава 9. Оптимизация программ

    наилучшим качеством. Во время интерактивного вращения (например, при нажатой клавише мыши) визуализировать модель с уменьшенным количеством примитивов. При ри­совании статичного изображения отображать модель пол­ностью.

    Аналогично, объекты, которые располагаются далеко от наблюдателя, могут быть представлены моделями пони­женной сложности. Это значительно снизит нагрузку на все ступени конвейера OpcnGL. Объекты, которые нахо­дятся полностью вне поля видимости, могут быть эффек­тивно отсечены без передачи на конвейер OpcnGL с по­мощью проверки попадания ограничивающих их простых объемов (сфер или кубов) в пирамиду зрения.

    9.1.2. Низкоуровневая оптимизация

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

    Желательно, чтобы использовались структуры данных, ко­торые могут быть быстро и эффективно переданы на конвейер OpenGL. Например, если мы хотим отобразить массив треуголь­ников, то использование указателя на этот массив значительно более эффективно, чем передача его OpenGL поэлементно.

    Пример. Предположим, что мы пишем приложение, которое реализует рисование карты местности. Один из компонентов ба­зы данных — список городов с их шириной, долготой и названи­ем. Соответствующая структура данных может быть такой:

    struct city

    {

    float latitute , longitude; /* положение города */
    char *name; /* название */

    9.1. Организация приложения

    117

    int large_flag; /* 0 = маленький, 1 = большой */

    };

    Список городов может храниться как массив таких структур. Допустим, мы пишем функцию, которая рисует города на карте в виде точек разного размера с подписями:

    void draw_cities( int n, struct city citylist [] )

    {

    int i ;

    for (i=0; i < n; i++)

    {

    if ( citylist [ i ]. large_flag)

    glPointSize( 4.0 ); else

    glPointSize( 2.0 );

    glBegin( GL_POINTS );

    glVertex2f( citylist [ i ] . longitude ,

    city list [ i ]. latitude ); glEnd();

    /* рисуем название, города */ DrawText ( citylist [ i ] . longitude , citylist [ i ] . latitude , citylist [ i ] . name); } }

    Эта реализация неудачна по следующим причинам:

    Ниже приведено более рациональное решение:

    void draw_cities( int n, struct city citylist [] ) {

    118

    Глава 9. Оптимизация программ


    }

    int i ;

    /* сначала рисуем маленькие точки */ glPointSize( 2.0 ); glBegin( GL_POINTS ); for ( i=0; i < n ; i++)

    {

    if ( city list [ i ]. large_flag==0) {

    glVertex2f( citylist [ i ] . longitude , city list [ i ]. latitude ); } }

    glEnd();

    /* большие точки рисуем во вторую очередь */ glPointSize( 4.0 ); glBegin( GL_POINTS ); for ( i=0; i < n ; i++)

    {

    if ( city list [ i ]. large_flag==l)

    {

    glVertex2f( citylist [ i ] . longitude , city list [ i ]. latitude ); } } glEnd();

    /* затем рисуем названия городов */ for ( i=0; i < n ; i++)

    {

    DrawText ( citylist [ i ] . longitude ,

    citylist [i]. latitude ,

    citylist [i]. name ) ; }

    В такой реализации мы вызываем glPointSize дважды и уве­личиваем число вершин между glBegin и glEnd.

    Однако остаются еще пути для оптимизации. Если мы поме-

    9.1. Организация приложения

    119

    няем наши структуры данных, то можем еще повысить эффек­тивность рисования точек. Например:

    struct city list

    { _

    int num_cities; /* число городов в списке */

    float ^position;/* координаты города */

    char **name; /* указатель на названия городов */

    float size ; /* размер точки, обозначающей город */

    };

    Теперь города разных размеров хранятся в разных списках. Положения точек хранятся отдельно в динамическом массиве. После реорганизации мы исключаем необходимость в условном операторе внутри glBegin/glEnd и получаем возможность исполь­зовать массивы вершин для оптимизации. В результате наша функция выглядит следующим образом:

    void draw_cities( struct city list * 1 i s t )

    {

    int i ;

    /* рисуем точки */ glPointSize( list >size );

    glVertexPointer( 2, GL_FLOAT, 0,

    list —>num_cities ,

    list >position ) ; glDrawArrays( GL_POINTS, 0, list->num_cities ); /* рисуем название города */ for (i=0; i < list —>num_cities ; i++)

    {

    DrawText( citylist [ i ] . longitude , citylist [ i ] . latitude citylist [i].name); } }

    120

    Глава 9. Оптимизация программ

    9.2. Оптимизация вызовов OpenGL

    9.2.1. Передача данных в OpenGL

    В данном разделе рассмотрим способы минимизации времени на передачу данных о примитивах в OpenGL.

    1   ...   12   13   14   15   16   17   18   19   ...   30


    написать администратору сайта