GLGDI+ или «переходим с GDI+ на OpenTK»

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

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

    OpenTK (Open Toolkit) — это низкоуровневая библиотека, которая является враппером для OpenGL, OpenGL ES, OpenCL и OpenAL. Данная библиотека предназначена для игр, научных приложений, а также для любых других приложений, которым требуется 3D-графика, аудио и вычислительная функциональность. OpenTK является кроссплатформенной библиотекой и работает как на Mono, так и на .NET.

    Почему выбор пал именно на OpenTK? Во-первых, OpenTK предоставляет класс GLControl (является прямым наследником UserControl), который позволяет упростить переход на данную библиотеку. Во-вторых, в комплекте идет класс TextPrinter, который позволяет довольно просто выводить текст на экран. В-третьих во время гугления я нашел небольшой архив «Engine.zip» с набором классов для 2D-отрисовки, инициализации OpenGL и прочими приятностями.

    Сначала я планировал описать какие подводные камни встретились мне при переходе на OpenTK, но, вспомнив, что вопрос перехода с GDI+ на что-то быстрое является довольно популярным, решил написать небольшую библиотеку, которая мимикрирует под GDI+ и выложить ее в открытом доступе. Назвал я ее GLGDI+. Помните, что это легковесная библиотека и содержит только самый необходимый минимум и не пытается полностью копировать API GDI+. Она содержит классы GLGraphics, GLImage и GLMultiImage. GLGraphics содержит следующие методы:
    • DrawString — выводит текст
    • DrawImage — рисует GLImage
    • DrawLine — рисует линию
    • DrawRectangle — рисует прямоугольник
    • FillRectangle — рисует закрашенный прямоугольник
    • DrawPoint — рисует точку
    • DrawPoints — рисует несколько точек
    • DrawMultiImage — рисует GLMultiImage (для отрисовки нескольких одинаковых изображений разом — это гораздо быстрее, нежели рисовать по одному, если таких изображений много)

    Некоторые моменты

    Я все же опишу некоторые моменты, с которыми мне пришлось столкнуться при использовании OpenTK. На сайте OpenTK есть хорошие туториалы, которые я, конечно же, не читал, ознакомься я с ними, и парой проблем было бы меньше. Но, что было, то было:
    1. Первое с чем я столкнулся: контрол вообще не перерисовывался при запуске, решилось просто, нужно не забыть вызвать метод SwapBuffers в конце OnPaint, GLControl уже имеет встроенную функциональность DoubleBuffer, нужно только переключить буфер
    2. Следующий момент, о который я споткнулся — это черные прямоугольники вместо изображений. Решалось вызовом image.SetBlending() перед отрисовкой, сейчас в библиотеке все изображения рисуются с блендингом, поэтому с этим проблем быть не должно
    3. Когда я второй контрол перевел на рельсы OpenTK, то оказалось, что первый контрол после этого перестал выполнять свои функции, решилось вызовом метода MakeCurrent в OnPaint перед отрисовкой элементов
    4. TextPrinter (основа для DrawString) иногда падает при выводе текста, тут ничего не поделаешь — класс глючный и на определенных сочетаниях качества отрисовки, шрифта и размера шрифта он падает, пришлось подбирать шрифт и размер
    5. Еще нужно отслеживать, что контрол загрузился и только после этого работать с OpenTK/GLGraphics, а также проверять, что контрол не в режиме дизайнера форм
    6. При изменении размеров контрола нужно не забыть вызвать GLGraphics.Resize(Width, Height)

    Заключение

    Библиотека лежит на GoogleCode, под BSD лицензией. Если кому понадобится — пользуйтесь на здоровье. Чтобы понять как работать с библиотекой — посмотрите исходный текст сэмпла, который идет в комплекте, он очень простой:

    Все описанные выше «моменты» в нем учтены.
    Данную библиотеку я пока не рекомендовал бы использовать для продуктов, нацеленных на массового пользователя — она слишком молода для этого, но в утилитах вполне пригодна к использованию.
    На данный момент планов по развитию библиотеки у меня нет — мне ее функционала хватает. Но багфиксы и патчи приветствуются :)

    Судя по тому, что я прочитал на OpenTK форуме, TextPrinter (используется для вывода текста) в будущем будет исключен из библиотеки, но, возможно, в отдельный проект. Так что его судьба пока что туманна. Сейчас он в состоянии Deprecated, поэтому дает warnings при компиляции библиотеки.

    Вот теперь редактор карт работает значительно быстрее и ничего не тормозит, чего и вам желаю!

    UPD: забыл указать ссылку на сайт OpenTK
    UPD2: исправил баг с путями в исходниках сэмпла (как в архиве, так и в SVN)
    Поделиться публикацией
    AdBlock похитил этот баннер, но баннеры не зубы — отрастут

    Подробнее
    Реклама

    Комментарии 27

      +3
      Direct2D + DirectWrite как-то более естественно подошли бы, не?
        +7
        Если вам Windows XP не нужна, тогда да. А если нужна, то нет. А если вам нужно еще и кроссплатформенное решение, то тем более.
          +4
          О кроссплатформенности вряд ли стоит думать, если речь о решении изначально на GDI+.

          Насчёт Windows XP вы были правы, но сами же говорите, что это не для массового пользователя, а на специфических АРМ всегда можно заявить Windows Vista в минимальных требованиях.

          В общем, при ваших исходных я бы предпочёл изучить Direct2D/DirectWrite. Благо есть уже наработки.
            0
            Понимаете — мне нужно, чтобы редактор работал на WindowsXP, он это делает, Direct2D нет.
              0
              почему Direct 2D не работает на XP? Managed DirectX прекрасно работает на XP. ибо он врапает обычный 9 DirectX, который в XP и появился
                +2
                Потому что вы путаете DirectDraw и Direct2D.
                en.wikipedia.org/wiki/Direct2D
                  +1
                  да. виноват. но все равно чем тогда DirectDraw вас не устроил?
                    +1
                    Больше не поддерживается Microsoft, и с ним тоже нужно разбираться, чтобы нарисовать изображение, линию, вывести текст. Для OpenTK же я нашел все (почти) готовое.
            0
            Я так понимаю, что openTK к винде особо не привязан?
              +1
              Вообще не привязан, насколько я знаю.
          +1
          Тоже ищу удобную обертку OpenGL под один из проектов. Правда с 3D.
          OpenTK уже год не обновлялся, что настораживает.
            +1
            opentk-1.0.0-rc1.exe 11.1 MB 2010-03-24

            Как бы еще только полгода :)
            А последние комиты, вообще всего месяц назад.
            +1
            не спец в этом деле, но вроде как в ОС которые ранее Win Vista OpenGL рисуется в оверлее, в отличие от нативного GDI?

            то есть это накладывает определенные ограничения. поправьте, если недостаточно информирован
              0
              Вроде как это миф, в который я кстати тоже долгое время верил, пока не прочитал статью http://www.opengl.org/pipeline/article/vol003_9/
                0
                Я тоже не спец в OpenGL. Но если речь идет о том же оверлее, который в видеоплеере, и с которого не снимается скриншот, то для OpenGL это не так.
                О каких ограничениях идет речь?
                0
                Скажите пожалуйста, а как обстоит дело с выводом кириллицы?
                  0
                  На скриншоте сэмплового проекта есть кириллица. С ней вроде все хорошо :)
                  +1
                  www.opentk.com забыли упомянуть
                  (на сайте находится очень толковый форум, в котором можно подискутировать с разработчиками)
                    0
                    Спасибо, добавил.
                    0
                    Интересная тема в целом. Тем временем, проверил сэмпл — не работает — exception.
                    MS C# Express 2008: все пересобрал, тоже самое:

                      0
                      Собственно это TextPrinter из OpenTK, о котором я писал, валится. Сам не знаю что с ним делать. Я думал, что он падает на каких-то определенных сочетаниях шрифтов, но похоже, что еще и на разных машинах по разному себя ведет.
                      У вас, надеюсь, шрифт «Arial» есть на машине?
                      0
                      У вас, надеюсь, шрифт «Arial» есть на машине?

                      Это не шутка? :)
                      Думаю Windows не станет загружаться без этого шрифта (шутка).
                      Отладчик показал проблему в строке bitmap = new Bitmap(path);
                      Собственно path — в порядке, вероятно mult.jpg в каком-то особом формате… Нет пока времени проверять, да и в шарпе я не силен, чтобы копнуть глубже.
                      В любом случае — отличное направление и статья — поэтому, всячески поддерживаю дальнейшую разработку врапера.
                        +1
                        Не шутка. За годы разработки софта с такими странностями встречаешься, что начинаешь допускать любые варианты, пока они не касаются магии…

                        Судя по скриншоту — проблема именно в TextPrinter.
                        А в отладчике падает по моей вине (я Debug path у себя менял), сейчас исправлю, спасибо.
                          0
                          Пофиксил пути. Архив на GoogleCode перезалил. Но в вашем случае, скорее всего, нужно подбирать «работающий» шрифт.
                          0
                          Если не секрет, а редактор к чему?
                            +1
                            Не секрет, к игре :)
                            «Дороги Рима»: www.realore.ru/games/roads_of_rome/

                            В течение недели напишу статейку о разработке оной. Тем более она уже вышла.
                            0
                            у меня на 7-ке пример выглядит вот так:



                            что я делаю не так?

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

                            Самое читаемое