Back to site

Интрефейс Fortran 2003 для OpenGL

Бібліятэка F03GL

Бібліятэка F03GL падае інтэрфейс Fortran 2003 для бібліятэкі OpenGL, а таксама камплект прылад GLU і GLUT. Ён быў распрацаваны Энтані Стоуном і Аляксандрам Донев. Мы ўжо атрымалі карысную інфармацыю ад некалькіх карыстачоў гэтай бібліятэкі, і мы ўдзячныя за іх прапановы. Існуе яшчэ магчымасці для ўдасканалення, і мы былі б рады атрымаць дадатковыя каментары і паведамленні пра памылкі.

Усе зыходныя коды, злучаныя з бібліятэкай F03GL, можна запампаваць у выглядзе ZIP архіва f03gl.zip ці сціснутага файла f03gl.tgz. Існуе файл README, які дае асноўныя інструкцыі па распакаванні і кампіляцыі файлаў і запуску тэстаў.

F03GL выкарыстоўвае З асаблівасці сумеснага функцыянавання сетак Fortran 2003 і злучаецца з З-інтэрфейсам для OpenGL. Такім чынам, любая сістэма, абсталяваная бібліятэкай OpenGL і загалоўкамі і кампілятарам Fortran, падтрымным З-узаемадзеянні, павінна з лёгкасцю выкарыстоўваць гэты інтэрфейс. У гэтым сэнсе F03GL адрозніваецца ад бібліятэкі f90gl, створанай Уільямам Ф. Митчеллом, якую можна знайсці па адрасе http://math.nist.gov/f90gl. Гэта бібліятэка рэалізуе афіцыйны інтэрфейс Fortran 90 OpenGL (прыняты OpenGL Architecture Review Board), апісаны ў NISTIR 6134.  Ён выкарыстоўвае спецыфічныя для кампілятара пакавання з мэтай рэалізацыі сродкаў Fortran і не выкарыстоўвае асаблівасці Fortran 2003. Бібліятэка F03GL павінна была быць лёгкім інтэрфейсам для З бібліятэкі, з мінімальным выкарыстаннем пакаванняў і нестандартных ці залежных ад працэсара функцый. Адрозненні паміж F03GL і NISTIR 6134 апісаны ў канцы гэтай старонкі. Да пераўтварэння кодаў з выкарыстаннем інтэрфейсу Fortran 90 павінна быць прыкладзена мінімум высілкаў. Мы пераўтварылі некалькі прыкладаў з размеркавання f90gl, каб выкарыстоўваць F03GL, і мы дзякуем доктара Митчелла за яго дазвол зрабіць гэта.

Стварэнне зыходных кодаў для F03GL

Зыходныя коды Fortran, утрымоўвалыя модулі з параметрамі дэкларацыі, інтэрфейснымі блокамі, а таксама некаторымі мінімальнымі пакаваннямі, ствараюцца аўтаматычна з дапамогай скрыптоў Perl. Адной з нашых мэт з'яўляецца распрацоўка прылад, якія могуць лёгка аўтаматызаваць пераўтварэнне асноўных З файлаў у модулі Fortran, для гэтага мы працуем з Крэйгам Расмуссеном з LANL з мэтай распрацоўкі XML стыляў, якія будуць скарыстаны для гэтай мэты (наведаеце CHASM toolkit webpage). Скрыпты Perl самі па сабе не вельмі складаныя і ўтрымоўваюць шмат забароненых доступаў для працы з інтэрфейсамі OpenGL, і яны, верагодна, могуць быць лёгка прыняты іншымі прыкладаннямі.

Для стварэння інтэрфейсаў GL і GLU, замест выкарыстання асноўных З файлаў GL.h і GLU.h (гэта некалькі рэдукаваныя версіі стандартных Linux gl.h і glu.h), мы вырашылі выкарыстоўваць ідэнтычную SGI спецыялізацыю для інтэрфейсаў у файлах gl.spec, enum.spec, glu.spec і enumglu.spec, якія можна знайсці па адрасе href="http://oss.sgi.com/projects/ogl-sample/registry">http://oss.sgi.com/projects/ogl-sample/registry. (Файлы, вылучаныя this red sanserif font , уключаны ў камплект f03gl).

У гэтыя файлы былі занесены толькі некалькі малаважных змен. Адмысловыя файлы забяспечваюць большую колькасць інфармацыі, чым З файлы: непример, яны даюць фіксаваную і абмежаваную інфармацыю для масіва аргументаў, а таксама дакументальна пацвярджаюць такія файлы, як бібліятэка OpenGL, захоўваючы паказальніка для ўнутранага выкарыстання. Мы паспрабавалі выкарыстоўваць усю гэту інфармацыю для падвышэння якасці інтэрфейсаў Fortran. Коды Fortran вырабляюцца з:

   spec_interfaces.pl --bozinit --PUBLIC -p . -d -m OpenGL -gl
   spec_interfaces.pl --bozinit --PRIVATE -p . -d -m OpenGL -glu

Выкананне spec_interfaces.pl дасць кароткую дакументацыю асноўных варыянтаў. Найболей важнымі з іх з'яўляецца варыянт “-m” ці “--module” які вырашае, які прэфікс у імёны модуля Fortran. Калі вы жадаеце замяніць f90gl у сваіх кодах (як мы робім у прыняцці некаторых яго прыкладаў), імёны модуляў павінны быць OpenGL_GL, OpenGL_GLU і OpenGL_GLUT. Калі вы жадаеце захаваць модулі f90gl і паспрабаваць новую бібліятэку F03GL, тады “-m F03GL” будзе добрым варыянтам. Калі ваш кампілятар Fortran не падтрымлівае канстанты BOZ (шаснаццатковыя канстанты выгляду z"0B04") у заявах параметру, адновіце інтэрфейсы без варыянту “--bozinit”. У адваротным выпадку, вы можаце проста выкарыстоўваць файлы OpenGL_gl.f90 і OpenGL_glu.f90 у пакеце f03gl.

Для бібліятэкі GLUT няма адмысловых файлаў, і мы выкарыстоўвалі З файлы для стварэння інтэрфейсаў. Існуюць таксама розныя бібліятэкі прылад, падобныя GLUT, і адпаведныя загалоўкі, а менавіта арыгінальны GLUT.h (ізноў жа, рэдукаваная версія glut.h з GLUT 3.8), створаная Маркам Д. Килгардом (SGI), якая не з'яўляецца агульнадаступнай, хоць яна і бясплатная, а таксама некалькі замен з адкрытым зыходным кодам, такія як FreeGLUT.h ад FreeGLUT ці OpenGLUT.h ад OpenGLUT. Мы пратэставалі скрыпт Perl h_interfaces.pl з усімі з гэтых бібліятэк і стварылі зыходныя коды OpenGL_glut.f90, OpenGL_freeglut.f90 і OpenGL_openglut.f90, выкарыстоўваючы:

   h_interfaces.pl -q --bozinit --scalar -m OpenGL -i GLUT.h

Убудаваныя шрыфты GLUT, якія лічацца несапраўднымі пры ўказаннях Са значэнняў, не могуць быць апрацаваны непасрэдна ў Fortran, дзе TYPE(C_PTR) – непразрысты тып, якому не могуць быць дадзены вызначаныя значэнні. Акрамя таго, розныя рэалізацыі GLUT апрацоўваюць шрыфты па-рознаму. Таму мы вырашылі дадаць GLUT_fonts.c і выкарыстоўваць нясталыя шрыфты TYPE(C_PTR) і папярэдне вызначаныя шрыфты. Пры гэтым для карыстача не бачныя яркія адрозненні. Ахоўваны атрыбут выкарыстоўваецца для таго, каб зрабіць гэтыя шрыфты сталага тыпу, але калі ваш кампілятар не падтрымлівае гэты атрыбут, проста выдаліце яго ў скрыпце Perl. Звернеце ўвагу, што glutInit быў перагружаны агульным інтэрфейсам, які дазваляе апусціць камандныя аргументы, бо звычайна яны не выкарыстоўваюцца ў кодах Fortran.

Апрацоўка зваротных выклікаў GLUT

Самая вялікая складанасць складаецца ў лячэнні зваротных выклікаў GLUT і, у прыватнасці, у іх выключэнні. Ёсць два спосабу прайсці працэдуры ( у якасці аргументаў) для З у Fortran 2003: як фіктыўныя працэдуры, якім могуць прадстаўлены ўсе інтэрфейсы, ці як працэдуры-паказальнікі (т. е. аргументы TYPE(C_FUNPTR), якія з'яўляюцца агульнымі паказальнікамі працэдуры). Мы аддаём перавагу стваральніка, бо выдача поўных інтэрфейсаў дапамагае кампілятарам пераканацца, што зваротныя выклікі карыстачоў абсталяваны чаканымі інтэрфейсамі. Тым не менш, пазней бывае цяжка выключыць зваротныя выклікі, якія ў GLUT ажыццяўляюцца шляхам мінання паказальніка функцыі NULL. У Fortran гэта лепш за ўсё рабіць з дапамогай фіктыўнай працэдуры, але гэта патрабуе выкарыстання пакаванняў, бо дадатковыя не могуць быць сумяшчальныя (пакуль). Карыстач проста апускае аргумент зваротнага выкліку для таго, каб адключыць яго. У NISTIR 6134, і ў блізкай адпаведнасці з З інтэрфейсамі адбываецца пастаўка фактычнага аргументу GLUT_NULL_FUNC. Сцэнар h_interfaces.glutnullfunc.pl стварае інтэрфейс, які испрользует некаторыя неадпаведныя прыёмы для выканання гэтай працы, пры гэтым захоўваючы праверку зваротнага выкліку інтэрфейсаў. Некаторыя аддаюць перавагу рабіць зваротныя выклікі TYPE(C_FUNPTR) і тэлефанаваць GLUT з З функцыямі напроста, без абгорткі (інтэрфейсы для іх ужо створаны скрыптамі Perl), але мы не заахвочваем гэта, бо гэта патрабуе змены паслядоўнасці выкліку (трэба ставіць C_FUNLOC у спіс фактычных аргументаў замест простага мінання працэдуры зваротнага выкліку) і можа прывесці да несумяшчальнасці паміж кодамі розных карыстачоў F03GL.

Аргументы радка знакаў

У F03GL аргументы радкоў перадаюцца як масівы знакаў [CHARACTER(C_CHAR), DIMENSION(*)] у адпаведнасці са стандартам F03, а не як радкі знакаў [CHARACTER(KIND=C_CHAR, LEN=*)]. Стандарт F03 мае адмысловыя коды доступу, якія дазваляюць перадавацца радкам у якасці фактычных аргументаў, але нулявы знак (C_CHAR_NULL) не добавлятся аўтаматычна, замест гэтага ён павінен дадавацца ўручную. У OpenGL_gl.f90, мы прапануем працэдуру-памагатага CString, якая пераўтворыць радок у нулявы масіў знакаў. Кодам карыстача трэба будзе замяняць такія радкі, як "text" у фактычным спісе аргументаў на CString("text").

Выкарыстанне F03GL

Калі крыніцы Fortran з модулямі OpenGL кампілююцца паспяхова, наступным крокам з'яўляецца іх тэставанне. Праграма
RandomSphere_OpenGLUT.f90 уяўляе сабою тэставую праграму ў фармаце падручніка. Гэта праграма выкарыстоўвае некаторыя з найболей карысных магчымасцяў Free/OpenGLUT, котоые канкуруюць з класічным GLUT у RandomSphere_GLUT.f90. Мы таксама адаптоўвалі некаторыя тэставыя ўзоры з f90gl для працы з f03gl. Выканаеце сцэнар Script.sh у кіраўніцтве f03gl, спачатку ўсталяваўшы кампілятар асяроддзя, падыходны адпаведнаму кампілятару каманд. Узоры былі пратэставаны з nagfor, gfortran і ifort. Пра дэталі, якія залежаць ад кампілятара, падрабязней у compiler notes.

Несумяшчальнасці з NISTIR 6134

Спіс несумяшчальнасцяў з NISTIR 6134:

  1. 1. Імёны модуляў могуць быць OpenGL_XXX, калі карыстач жадае замяніць f90gl, у адваротным выпадку яны павінны быць F03GL_XXX.
  2. 2. F03GL не працуе з працэсарамі з недахопам кароткіх тыпаў. Ён толькі вызначае, да прыкладу, GLshort=C_SHORT, дзе C_SHORT з'яўляецца параметрам, апісаным у F2003 intrinsic ISO_C_BINDING. Гэта можа быць -1, калі працэсар не падтрымлівае такі выгляд пытання, што азначае, што праграма, якая выкарыстоўвае гэты выгляд параметру, проста не будзе кампілявацца. Я лічу, што на сённяшні дзень гэта не праблема, бо ўсе працэсары падтрымліваюць З набор стандартных цэлых тыпаў.
  3. 3. GLboolean з'яўляюцца INTEGER(GLboolean)=INTEGER(C_SIGNED_CHAR), а не LOGICAL, у адпаведнасці са стандартам F2003. LOGICAL(C_BOOL) працуе толькі з C99's _Bool. Для іншых «лагічных лікаў» у З (у двукоссях, бо насамрэч яны з'яўляюцца цэлымі лікамі) трэба выкарыстоўваць INTEGER.
  4. 4. Char становіцца CHARACTER(KIND=C_CHAR), вынікаючы F2003. Амаль на ўсіх працэсарах, калі не на ўсіх, гэта тое ж самае, як калі стандартнае CHARACTER. char* становіцца масівам ["CHARACTER(C_CHAR), DIMENSION(*)"], а не простым камандным радком.
  5. 5. Функцыі, якія вяртаюць паказальнікі, а асабліва char*, пераходзяць у TYPE(C_PTR), у агульны З паказальнік. Яны могуць быць ператвораны ў паказальнік масіва тыпу CHARACTER(KIND=C_CHAR), выкарыстоўваю F2003 працэдуру C_F_POINTER. Мы не падаём для гэтага функцыю ўсярэдзіне F2003, але яе лёгка вывесці. Пераўтварэнне іх у паказальнікі тыпу CHARACTER(KIND=C_CHAR,LEN=:) нелегальна ў адпаведнасці з F2003, бо іх даўжыня не павінна перавышаць 1 для ўзаемадзеяння з іншымі праграмамі.
  6. 6. TYPE(GLCPTR) становіцца TYPE(C_PTR), і GLNULLPTR - C_NULL_PTR у адпаведнасці з F2003. Нажаль, у F2003 не TYPEALIAS.
  7. 7. F2003 не вызначае такія карыстацкія тыпы, як gluQuadricObj ці TK_RGTImageRec. Калі гэтыя тыпы кіруюцца паказальнікам, тое выкарыстоўваецца аргумент TYPE(C_PTR). Пры неабходнасці можна вызначыць вытворныя тыпы, але гэта не абавязкова для базавых бібліятэк, бо кампаненты сістэмы тут не патрэбныя.
  8. 8. Адсутныя аргуметы становяцца TYPE(C_PTR)---, і няма агульнага інтэрфейсу, бо гэта не ўпісваецца ў стандарт F2003. Толькі TYPE(C_PTR) узаемадзейнічае з “void*”.
  9. 9. Працэдуры перастаюць быць агульнымі, а больш спецыфічнымі ў адносінах да З інтэрфейсам (якія, як преполагалось, маюць вонкавыя радкі). У наш час адзіным выключэннем з'яўляецца glutInit, які быў перагружаны, таму ён можа быць названы без аргументаў.
  10. 10. Не было зроблена скарачэнні да 31 элемента. Гэта можа быць аўтаматычна зроблена працэсарам Fortran, а менавіта, ён будзе ігнараваць усе аб'екты, вялікія ці роўныя 32.
  11. 11. Быў выдалены GLUTNULLFUNC (гл. над абмеркаваннем зваротных званкоў GLUT). Мы забяспечваем версію інтэрфейсаў GLUT, дзе можа быць скарыстана функцыя GLUTNULLFUNC. Замест гэтага, проста выкарыстоўвайце працэдуру GLUT без ужывання фактычнага аргументу для выключэння зваротных званкоў. Звернеце ўвагу, што для гэтага можа запатрабавацца выкарыстанне пароляў, калі дадатковы аргумент зваротнага выкліку не апошні ў спісе аргументаў.
  12. 12. У выпадках, калі GL утрымлівае паказальнік у фактычнага аргументу, як у glFeedbackBuffer (секцыя 4.2 у NISTIR), F03GL выкарыстоўвае TYPE(C_PTR) фіктыўны аргумент замест усталёўкі атрыбуту мэты на фіктыўны аргумент, што можа не спрацаваць. Адзіныя выпадкі, калі стандарт Fortran 2003 гарантуе тое, што інфармацыя не будзе скапіявана, гэта калі фіктыўны аргумент выдуманы і мае вызначаную мэту, тады выдуманы аргумент узаемадзейнічае з іншымі аргументамі (наогул, гэта будзе даступна толькі ў будучыні F2008).
  13. 13. Зваротныя званкі GLUT павінны мець аргументы з атрыбутам каштоўнасці і мець знак BIND(C), каб яны былі выкліканы напроста з С. Звернеце ўвагу, што BIND(C,NAME="") можа быць скарыстаны для прыгнечання афіцыйных пазнак для падпраграм, якія патрэбныя толькі ў якасці зваротных выклікаў. Гэта дазваляе пазбегнуць запарушванні глабальнай прасторы назваў знакаў зваротнымі выклікамі.
Published (Last edited): Apr 15 , source: http://www-stone.ch.cam.ac.uk/pub/f03gl/