Skip to main content

Блог инженера

Блог о минимализме, инжинерии и программировании.



Компьютерная графика на языке программирования Форт. Часть 1.

  | #Форт#программирование

В прошлой публикации я предположил, что можно относительно просто расширить реализацию Форта pForth для работы с компьютерной графикой. Это оказалось правдой, но путь был тупиковым. Немного подробнее об этом.

Я решил расширить Форт привязкой к библиотеке компьютерной графики SDL. Плюсы достаточно очевидны, например, есть реализация Lua расширенная привязками к SDL, это проект LÖVE. Я собирался сделать самые простые привязки, открытие окна, текст, примитивная компьютерная графика. Задача казалась сложной из-за того, что SDL не такая уж простая библиотека. Чтобы делать привязки нужно было бы сперва разобраться с программированием, а даже простые руководства содержат по десять полноценных уроков.

Когда я искал более простые графические библиотеки, доступные на Си, то обнаружил удивительно много примеров программ и описаний BGI. Когда-то это была практически единственная доступная графическая библиотека для Си на ДОС. Библиотека действительно очень простая и учебная курва для неё очень пологая. Достаточно базового знания Си и пары примеров. Также, эта библиотека работала с Паскалем. Одна беда, это был продукт исключительно для ДОС, Borland не стали реализовывать эту библиотеку в Windows.

К счастью, оказалось минимум два проекта, которые воспроизводят BGI. Причём несколько проектов - кроссплатформенные. Именно они заинтересовали меня в первую очередь. Я выбрал проект SDL_bgi. Он наиблее живой из всех, на него неплохие отзывы. И сайт проекта весьма неплох. Не всё вышло гладко, но этот проект позволил мне разобраться, где “подводные камни” моего намерения и сделать это достаточно быстро и безболезненно.

Компиляция SDL_bgi

Некоторое время я потратил пытаясь просто скомпилировать примеры с сайта проекта. Для Windows библиотека SDL_bgi выложена только с dll файлом. К сожалению, Pelles C не умеет компилировать программы с dll, ему нужен файл lib. По крайней мере, мне не удалось разобраться, как это сделать. Поэтому я установил Code::blocks. С технической точки зрения, компиляция программы с использованием этой библиотеки в Code::blocks не представляет особой сложности. Нужно явно указать компилятору, где лежат библиотечные файлы, где заголовочные и явным образом указать линкеру файл “SDL_bgi.dll”. Примеры скомпилировались. Я написал собственную учебную программу и это оказалось очень несложно.

Связывание SDL_bgi и pForth

Это тоже оказалось весьма несложным. pForth легко скомпилировался в Code::blocks. Пользовательские слова Форт для привязки к библиотекам Си можно определять в файле pfcustom.c. Файл небольшой, имеет простую структуру, а комментарии отлично описывают весь процесс. Мне не понадобилось дополнительных описаний, чтобы определить Форт слова для создания и закрытия графического окна, рисования линий. Я выложил сборку pForth с графическими привязками и файл исходного кода pfcustom.c с изменениями в общий доступ. Но у использования графической библиотеки SDL_bgi в форт оказались неприятные эффекты.

Библиотека SDL, как и большинство других графических библиотек работают в цикле событий. Т.е. графическая оболочка - “хозяин”, в ней непреывно работает цикл, который проверяет, не нажата ли кнопка, пункт меню, какие клавиши нажаты и т.п. Чтобы библиотека полноценно работала в Форт - нужно было бы сделать и обработчики событий, но мне нужно только вывести в графическое окно графические примитивы. Без обработчика событий поведение окна становится неопределённым, оно зависает. Если в форт-слово создания окна включить цикл обработки событий - он никогда не вернёт управление обратно форту. Если не запускать цикла - поведение окна становится неопределённым. Иногда в нём можно что-то начертить и обновить его. Иногда - нет. В любом случае, это не то поведение, что мне нужно. Технически, можно определить все слова для рисования в одно форт-слово, на закрытие окна повесить обработчик событий ожидания нажатия любой кнопки. Тогда форт начертит всё, что ожидалось, покажет окно, передаст ему управление. А окно вернёт управление и уничтожится после нажатия клавиши. Это может быть определение слова такого вида.

: GRAPH
600 800 INITGRAPH
10 200 LINETO
80 160 LINETO
500 1200 2 / LINETO
REFRESH
CLOSEGRAPH ;

Здесь все слова, которые я создал. Такой подход работает. CLOSEGRAPH - это как раз то слово, которое уничтожает графическое окно после нажатия любой клавиши. К сожалению, библиотека SDL_bgi некорректно уничтожает окно. Попытка создать графическое окно повторно приводит к ошибке, после которой Форт завершает работу. Так что никакая отладка невозможна.

Форт и графика

Можно было было бы попрбовать другую библиотеку BGI, она должна была бы заработать без изменения кода. Возможно, другая библиотека могла бы справиться с работой вне цикла событий или более корректно уничтожала бы графическое окно. Может быть, можно было бы запускать графическое окно отдельным процессом, чтобы его краш не вызывал краша Форта, а в окне работал бы нормальный цикл событий но работал на опрос сообщений из Форта. Но всё это лишь усложняет то, что должно было бы быть простым. Я не собираюсь делать динамические сцены или даже простые игры на Форт. Я собираюсь реализовать ту компьютерную графику, которую не смог реализовать, когда мне было 15. Знаний не хватило. Но хочу сделать это необычным и даже извращённым способом. Например, на языке программирования Форт. Поэтому такое усложнение задачи мне не нужно. Есть принципиально другой подход.

У нас был компилятор Си, стандартные Си библиотеки, мощнейшая форт-машина, немного свободного времени, а ещё доступ в интернет и дюжина книг по компьютерной графике. Не то, чтобы всё это было нужно для того, чтобы нарисовать пару объёмных додекаэдров на экране, но раз начал программировать, то иди в своём увлечении до конца. Единственное, что меня беспокоило - это сомнительные пользовательские библиотеки для работы с графикой. Нет никого более беспомощного, безответственного и безнравственного, чем человек использующий эти одноразовые поделки. И я знал, что довольно скоро мы в это окунёмся.

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

About Mikhail Kiselev

Photo of Mikhail Kiselev

Приветствую в моём блоге! 😄 Меня зовут Михаил. Я инженер и программист. Живу в Израиле. Но мой блог связан с работой в Сибири и на Сахалине, путешествую где придётся. Я предпочитаю пост в блог посту в твиттер. Описание полезной технологии или гаджета предпочитаю описанию заката или посиделок в кафе.