[Haskell-cafe] OpenGL and GLUT in GHC
sven.panne at aedion.de
Sat Mar 24 11:41:09 EDT 2007
[ Small note: Library-related questions should better be directed to
libraries at haskell.org, and for mails regardind the OpenGL/GLUT packages there
is the hopengl at haskell.org mailing list. ]
On Saturday 24 March 2007 13:37, Ruben Zilibowitz wrote:
> [...] I've encountered a strange bug which I'm having trouble with. If I
> render a sphere and a plane, then the plane is facing the wrong way
> and is shaded on the wrong side. If however I only render the plane
> then it appears to be facing the right way and is shaded on the
> correct side. [...]
I guess the problem is a misunderstanding of what 'autoNormal $= Enabled'
does. It enables the automatic generation of analytic normals when 2D
evaluators are used. It doesn't affect the rendering of normal primitives
like quads. You don't provide any normals for your plane, so the current
normal is used for all four vertices. The value of the current normal is
(Vector 0 0 1) initially, so this seems to work if you render the plane
alone, *but* the GLUT object rendering functions provide normals for all
their vertices. So the net effect is that the normals for the vertices of
your plane are set to whichever normal GLUT has specified last. Simple fix:
Provide normals for your quad, i.e. use
normal (Normal3 0 0 (1 :: GLfloat))
before specifying any vertex of your quad. In general when lighting is used,
make sure to provide the correct normals for all vertices. Unit normals
should be preferred, otherwise you have to tell OpenGL about that and this
leads to more work (= rescaling/normalization of all normals within OpenGL).
A few more notes:
* There is no need in your example to use 'normalize $= Enabled' when you
provide unit normals. GLUT does this, BTW.
* Setting the material properties could be done only once in the
* Use postRedisplay only when something has really changed, e.g. at the end
of 'motion'. Otherwise you get 100% CPU/GPU load for no good reason.
* IORefs are StateVars, so you can use get and ($=) instead of readIORef
and writeIORef, this is more consistent with the OpenGL/GLUT API.
More information about the Haskell-Cafe