"неизвестный GLU-вход gluOrtho2D" с использованием opengl в Haskell

Я на Ubuntu 11.10, используя версию ghc 7.0.3.20110330, на которой запущены "текущие версии обновлений" драйвера отображения nvidia. Вы можете воспроизвести, выполнив:

curl http://ix.io/1t6 > Stroke.hs; ghc --make Stroke.hs; ./Stroke
...
Stroke: user error (unknown GLU entry gluOrtho2D)

Но я могу запустить opengl, и он работает нормально. Я пробовал glxgears, и все получилось отлично, и я запустил контрольный тест opengl, и он тоже отлично работал.

Версии haskell opengl libs результат работы:

for p in OpenGL OpenGLRaw GLURaw; do ghc-pkg latest $p; done

OpenGL-2.4.0.1
OpenGLRaw-1.1.0.1
GLURaw-1.1.0.0

Ответ 1

Это определенная ошибка. Существует проблема с компоновщиком (и я не уверен, что это относится к 11.10 или к GHC 7.0+). Здесь, как мне было объяснено: компоновщик по существу решает, что, поскольку вы не связываете статически с libglut, он просто оптимизирует, не связывая ваш исполняемый файл с ним вообще. Вы можете обойти это, применив следующий патч к GLURaw 1.1.0.0:

diff -ur GLURaw-1.1.0.0.orig/cbits/HsGLURaw.c GLURaw-1.1.0.0/cbits/HsGLURaw.c
--- GLURaw-1.1.0.0.orig/cbits/HsGLURaw.c    2011-05-12 09:02:30.000000000 +1200
+++ GLURaw-1.1.0.0/cbits/HsGLURaw.c 2011-05-11 23:08:10.000000000 +1200
@@ -68,6 +68,9 @@

 #include <stdlib.h>
 #include <dlfcn.h>
+#include <stdio.h>
+#include <GL/glu.h>
+

 void*
 hs_GLU_getProcAddress(const char *name)
@@ -80,6 +83,7 @@
     /* Get a handle for our executable. */
     handle = dlopen(NULL, RTLD_LAZY);
   }
+  printf("%p\n", gluBeginCurve);

   return handle ? dlsym(handle, name) : NULL;
 }
Only in GLURaw-1.1.0.0: dist

Запустите cabal install на GLURaw после применения этого патча, и он должен избавиться от этой проблемы.

Ответ 2

Я получаю, что он работает, изменяя шаг компиляции:

ghc --make Stroke.hs -lGL -lGLU -lglut

У меня есть версии (я не установил OpenGLRaw, GLURaw):

cabal list *

* OpenGL
    Default available version: 2.4.0.1
    Installed versions: 2.2.3.0
* OpenGLRaw
    Default available version: 1.1.0.1
    Installed versions: [ Not installed ]
* GLURaw
    Default available version: 1.1.0.0
   Installed versions: [ Not installed ]

EDIT: я использую Ubuntu 11.04 и GHC 7.0.3 с платформой Haskell 2011.2.0.1

Ответ 3

Я скомпилировал его в своей системе (Mac OS 10.7.2 с GHC 7.2.1), и он работал здесь, поэтому программа должна быть правильной. Мои версии пакета

GLURaw-1.1.0.0
GLUT-2.2.2.0
OpenGL-2.4.0.1
OpenGLRaw-1.1.0.1

Возможно, вы могли бы попробовать найти простой пример C/С++, который использует gluOrtho2D и посмотреть, работает ли это?

Ответ 4

Похоже, что использование GLU в значительной степени устарело как OpenGL 3.0, из которого более высокие версии использовались с пакетов Haskell OpenGL-2.4. Там упоминается OpenGL wiki, в котором говорится:

GLU - библиотека Utility OpenGL - это дополнительная библиотека, которая содержит несколько функций для дополнительных задач. это было традиционным и можно найти во многих учебниках и примерах. Но GLU использует множество функций OpenGL, которые устарели сейчас. внутренняя матрица проецирования больше не должна использоваться, поэтому программист должен использовать замену gluPerspective, вместо этого обновления внутренней матрицы проекции вернет эту матрицу.

Это означает, что функции в Graphics.Rendering.OpenGL.GLU.Matrix больше не должны использоваться. Это включает в себя:

ortho2D
perspective
lookAt
pickMatrix
project
unProject
unProject4 

Я подозреваю, что это может быть причиной того, что ваш код компилируется, но не работает, когда используется ortho2D.

Возможно, возникнет соблазн использовать glOrtho вместо gluOrtho2D, так как мы имеем:

ortho2D left right bottom up = ortho left right bottom up (-1) 1

Однако, согласно OpenGL spec, кажется, что даже glOrtho устарел с OpenGL 3.1. На момент написания статьи использование ortho вместо ortho2D работает с использованием этой эквивалентности.

Я заметил, что один комментатор также столкнулся с функцией perspective. Здесь один из способов реализовать его самостоятельно, не используя GLU (но все же используя функцию, устаревшую в OpenGL 3.1):

import qualified Graphics.Rendering.OpenGL as GL

perspective :: GL.GLdouble -> GL.GLdouble -> GL.GLdouble -> GL.GLdouble -> IO ()
perspective fovy aspect near far =
  GL.frustum xmin xmax ymin ymax near far
 where ymax = near * tan (fovy * pi / 360.0)
       ymin = - ymax
       xmax = ymax * aspect
       xmin = ymin * aspect