[Haskell-cafe] OpenGL and GLUT in GHC

2007-03-24 Thread Ruben Zilibowitz

Hi,

I'm experimenting using OpenGL and GLUT in Haskell using GHC. There  
are modules Graphics.Rendering.OpenGL and Graphics.UI.GLUT. I am  
using these.


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 have made the source file available as a download here:
http://www.cse.unsw.edu.au/~rubenz/stuff/test.hs

It can be built by running: ghc --make test.hs
I am using ghc 6.6

There is a comment in the source file saying: Commenting out the  
line below here causes the plane to be rendered facing towards the  
camera...
The bug can be seen by commenting out the line of code that follows  
and recompiling.


If anyone can help me by explaining why I am getting this bug or how  
to fix it that would be great. I'd be very appreciative.


Cheers,

Ruben

___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] OpenGL and GLUT in GHC

2007-03-24 Thread Sven Panne
[ Small note: Library-related questions should better be directed to 
[EMAIL PROTECTED], and for mails regardind the OpenGL/GLUT packages there 
is the [EMAIL PROTECTED] 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 
initialization function.

   * 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.

Cheers,
   S.
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe