Claus Reinke | 2 Dec 2008 20:57

Re: [Haskell-cafe] Re: [Haskell] GHC 6.10 and OpenGL

> I believe these errors are caused by the wrong calling convention
> being used in the Haskell bindings. This part in the configure script
> tests the build (host) platform:
> 
> case "$host" in
> *-mingw32) CALLCONV=stdcall ;;
> *)      CALLCONV=ccall ;;
> esac
> 
> Since it doesn't test for Cygwin, you end up with the calling
> convention being ccall, which leads to the linker errors because of
> associated name mangling (you would also see run-time crashes if you
> managed to somehow link your program).

Ah, that makes sense! And, indeed, for the archives, this workaround 
fixes the issue (even when building from cygwin bash):

    cabal install opengl glut --configure-option="--host=i386-unknown-mingw32" --reinstall

Thanks, now FunWorlds can ride again!-)

I suppose we could document this on the OpenGL wiki, but even
better would be a fix to OpenGL's configure (apart from checking 
the build environment (mingw) rather than the host (cygwin here), it 
should ensure that the build uses exactly what configure has tested 
successfully) or .cabal (allways setting the --host configure option 
if on windows)?

[cc-ed to hopengl list, since this seems to be an OpenGL-specific 
 issue, not a general Cabal one; Cabal++ :-]
(Continue reading)

Claus Reinke | 4 Dec 2008 18:52

Re: noticing freeglut vs not

Is this still an open issue in FieldTrip? If you look at the online versions 
of the files Sven mentioned

    http://darcs.haskell.org/packages/GLUT/include/HsGLUTExt.h
    http://darcs.haskell.org/packages/GLUT/Graphics/UI/GLUT/Extensions.hs

you can see how the dynamic lookup of functions that are only 
available in some extensions is handled. Looking at

    http://darcs.haskell.org/packages/GLUT/Graphics/UI/GLUT/Begin.hs

it does seem as if constants and StateVars are not directly protected like 
this, but 'actionOnWindowClose' calls 'glutSetOption', which you can see in 

    http://darcs.haskell.org/packages/GLUT/Graphics/UI/GLUT/QueryUtils.hs

as just such a dynamic lookup. In case this isn't clear: your code can
simply catch the exception thrown when that dynamic lookup fails,
letting the exception handler pursue an alternative path (since your ticket
recommends commenting out that line, the handler could perhaps just do 
nothing in your case, or issue a warning about missing freeglut?).

No change to the GLUT package should be needed, I think.
Claus

> Thanks for the pointers.
> 
> I'm looking for some way to program my library so that a graceful exit is
> made where possible and still runs, though exits less gracefully with
> non-free glut.  I'd be happy with either a new API entry for that case or a
(Continue reading)

Corey O'Connor | 17 Dec 2008 09:32
Picon

EXT_framebuffer_object support.

Hello all,
I searched for current efforts on adding EXT_framebuffer_object
support to HOpenGL but was unable to locate anything.
I've added the very beginnings of EXT_framebuffer_object support.
Attached (in theory) is the current patch.
I've only added the bare minimum required to render to a 2D texture
and am not sure if the style matches the current style.

If the patch was stripped from this email the changes can be pulled from:
    http://www.tothepowerofdisco.com/repo/OpenGL

Cheers,
Corey O'Connor
_______________________________________________
HOpenGL mailing list
HOpenGL <at> haskell.org
http://www.haskell.org/mailman/listinfo/hopengl
Balazs Komuves | 17 Dec 2008 13:19
Picon

Re: EXT_framebuffer_object support.


Hello,

Actually I did the exact same thing. My "EXT_framebuffer_object" support is fairly complete,
and I tried to match the existing style, but it is not really tested apart from a simple example.
I also attached a patch which adds support for using Vertex Attributes in Vertex Arrays (which
is standard OpenGL, not an extension, but was missing), but that one is completely untested;
and also a bugfix (uniformLocation and friends).

Balazs

On Wed, Dec 17, 2008 at 9:32 AM, Corey O'Connor <coreyoconnor <at> gmail.com> wrote:
Hello all,
I searched for current efforts on adding EXT_framebuffer_object
support to HOpenGL but was unable to locate anything.
I've added the very beginnings of EXT_framebuffer_object support.
Attached (in theory) is the current patch.
I've only added the bare minimum required to render to a 2D texture
and am not sure if the style matches the current style.

If the patch was stripped from this email the changes can be pulled from:
   http://www.tothepowerofdisco.com/repo/OpenGL

Cheers,
Corey O'Connor

_______________________________________________
HOpenGL mailing list
HOpenGL <at> haskell.org
http://www.haskell.org/mailman/listinfo/hopengl


Wed May 28 15:33:56 CEST 2008  Balazs Komuves <bkomuves <at> gmail.com>
  * fixes the withCAStringLen bug in Shaders.hs

Sat Oct 25 14:33:52 CEST 2008  Balazs Komuves <bkomuves <at> gmail.com>
  * initial Vertex Attributes support in Vertex Arrays (untested)

Wed Dec  3 21:50:20 CET 2008  Balazs Komuves <bkomuves <at> gmail.com>
  * initial FBO support (EXT_framebuffer_object)

Wed Dec 17 13:04:54 CET 2008  Balazs Komuves <bkomuves <at> gmail.com>
  * more FBO support/fixes

New patches:

[fixes the withCAStringLen bug in Shaders.hs
Balazs Komuves <bkomuves <at> gmail.com>**20080528133356] {
hunk ./Graphics/Rendering/OpenGL/GL/Shaders.hs 42
 import Control.Monad.Fix ( MonadFix(..) )
 import Data.Int
 import Data.List ( genericLength, (\\) )
-import Foreign.C.String ( peekCAStringLen, withCAStringLen )
+import Foreign.C.String ( peekCAStringLen, withCAStringLen, withCAString )
 import Foreign.Marshal.Alloc ( alloca, allocaBytes )
 import Foreign.Marshal.Array ( allocaArray, withArray, peekArray )
 import Foreign.Marshal.Utils ( withMany )
hunk ./Graphics/Rendering/OpenGL/GL/Shaders.hs 86
    withCAStringLen s $ \(p,len) ->
       act (castPtr p, fromIntegral len)
 
+withGLString :: String -> (Ptr GLchar -> IO a) -> IO a
+withGLString s act =
+   withCAString s $ \p ->
+      act (castPtr p)
+
 --------------------------------------------------------------------------------
 
 newtype VertexShader = VertexShader { vertexShaderID :: GLuint }
hunk ./Graphics/Rendering/OpenGL/GL/Shaders.hs 400
 
 getAttribLocation :: Program -> String -> IO AttribLocation
 getAttribLocation program name =
-   withGLStringLen name $ \(buf,_) ->
+   withGLString name $ \buf ->
       fmap (AttribLocation . fromIntegral) $
         glGetAttribLocation program buf
 
hunk ./Graphics/Rendering/OpenGL/GL/Shaders.hs 408
 
 bindAttribLocation :: Program -> AttribLocation -> String -> IO ()
 bindAttribLocation program location name =
-   withGLStringLen name $ \(buf,_) ->
+   withGLString name $ \buf ->
       glBindAttribLocation program location buf
 
 EXTENSION_ENTRY("OpenGL 2.0",glBindAttribLocation,Program -> AttribLocation -> Ptr GLchar -> IO ())
hunk ./Graphics/Rendering/OpenGL/GL/Shaders.hs 499
 uniformLocation :: Program -> String -> GettableStateVar UniformLocation
 uniformLocation program name =
    makeGettableStateVar $
-      withGLStringLen name $ \(buf,_) ->
+      withGLString name $ \buf ->
          fmap UniformLocation $
             glGetUniformLocation program buf
 
}
[initial Vertex Attributes support in Vertex Arrays (untested)
Balazs Komuves <bkomuves <at> gmail.com>**20081025123352] {
hunk ./Graphics/Rendering/OpenGL/GL/QueryUtils.hs 25
    getEnum1,
    getSizei1,
    getFloat1, getFloat2, getFloat3, getFloat4, getFloatv,
-   getDouble1, getDouble2, getDouble4, getDoublev
+   getDouble1, getDouble2, getDouble4, getDoublev,
+   getVertexAttribInteger1, getVertexAttribIntegerv,
+   getVertexAttribEnum1, getVertexAttribBoolean1
 ) where
 
 import Foreign.Marshal.Alloc ( alloca )
hunk ./Graphics/Rendering/OpenGL/GL/QueryUtils.hs 34
 import Foreign.Marshal.Array ( allocaArray )
 import Foreign.Ptr ( Ptr )
 import Graphics.Rendering.OpenGL.GL.BasicTypes (
-   GLboolean, GLenum, GLint, GLsizei, GLfloat, GLdouble )
+   GLboolean, GLuint, GLenum, GLint, GLsizei, GLfloat, GLdouble )
 import Graphics.Rendering.OpenGL.GL.PeekPoke ( peek1, peek2, peek3, peek4 )
 import Graphics.Rendering.OpenGL.GLU.ErrorsInternal ( recordInvalidEnum )
hunk ./Graphics/Rendering/OpenGL/GL/QueryUtils.hs 37
+import Graphics.Rendering.OpenGL.GL.Extensions (
+   FunPtr, unsafePerformIO, Invoker, getProcAddress )
+
+--------------------------------------------------------------------------------
+
+#include "HsOpenGLExt.h"
 
 --------------------------------------------------------------------------------
 
hunk ./Graphics/Rendering/OpenGL/GL/QueryUtils.hs 296
    | GetMatrixIndexArraySize
    | GetMatrixIndexArrayType
    | GetMatrixIndexArrayStride
+   
+   | GetVertexAttributeArrayEnabled 
+   | GetVertexAttributeArraySize 
+   | GetVertexAttributeArrayType 
+   | GetVertexAttributeArrayStride 
+   | GetVertexAttributeArrayNormalized  -- these are client state, except CurrentVertexAttribute
+   | GetCurrentVertexAttribute 
+   
    | GetClipPlane GLsizei
    | GetLight GLsizei
    | GetTransposeModelviewMatrix
hunk ./Graphics/Rendering/OpenGL/GL/QueryUtils.hs 686
    GetMatrixIndexArraySize -> Just 0x8846
    GetMatrixIndexArrayType -> Just 0x8847
    GetMatrixIndexArrayStride -> Just 0x8848
+   
+   GetVertexAttributeArrayEnabled -> Just 0x8622
+   GetVertexAttributeArraySize -> Just 0x8623
+   GetVertexAttributeArrayType -> Just 0x8625
+   GetVertexAttributeArrayStride -> Just 0x8624
+   GetVertexAttributeArrayNormalized -> Just 0x886a
+   GetCurrentVertexAttribute -> Just 0x8626
+   
    GetClipPlane i -> clipPlaneIndexToEnum i
    GetLight i -> lightIndexToEnum i
    GetTransposeModelviewMatrix -> Just 0x84e3
hunk ./Graphics/Rendering/OpenGL/GL/QueryUtils.hs 976
 
 foreign import CALLCONV unsafe "glGetDoublev" glGetDoublev ::
    GLenum -> Ptr GLdouble -> IO ()
+   
+--------------------------------------------------------------------------------
+
+getVertexAttribInteger1 :: (GLint -> a) -> GLuint -> GetPName -> IO a
+getVertexAttribInteger1 f index n = alloca $ \buf -> do
+   getVertexAttribIntegerv index n buf
+   peek1 f buf
+
+getVertexAttribEnum1 :: (GLenum -> a) -> GLuint -> GetPName -> IO a
+getVertexAttribEnum1 f = getVertexAttribInteger1 (f . fromIntegral)
+
+getVertexAttribBoolean1 :: (GLboolean -> a) -> GLuint -> GetPName -> IO a
+getVertexAttribBoolean1 f = getVertexAttribInteger1 (f . fromIntegral)
+
+getVertexAttribIntegerv :: GLuint -> GetPName -> Ptr GLint -> IO ()
+getVertexAttribIntegerv index = maybe (const recordInvalidEnum) (glGetVertexAttribiv index) . marshalGetPName
+
+EXTENSION_ENTRY("OpenGL 2.0",glGetVertexAttribdv,GLuint -> GLenum -> Ptr GLdouble -> IO ())
+EXTENSION_ENTRY("OpenGL 2.0",glGetVertexAttribfv,GLuint -> GLenum -> Ptr GLfloat  -> IO ())
+EXTENSION_ENTRY("OpenGL 2.0",glGetVertexAttribiv,GLuint -> GLenum -> Ptr GLint    -> IO ())
+
hunk ./Graphics/Rendering/OpenGL/GL/VertexArrays.hs 41
    EnableCap(CapVertexArray,CapNormalArray,CapColorArray,CapIndexArray,
              CapTextureCoordArray,CapEdgeFlagArray,CapFogCoordArray,
              CapSecondaryColorArray,CapMatrixIndexArray,CapPrimitiveRestart),
-   makeCapability )
+   makeCapability, unmarshalCapability )
 import Graphics.Rendering.OpenGL.GL.BasicTypes (
hunk ./Graphics/Rendering/OpenGL/GL/VertexArrays.hs 43
-   GLboolean, GLenum, GLint, GLuint, GLsizei, Capability(Enabled) )
+   GLboolean, GLenum, GLint, GLuint, GLsizei, Capability(..) )
 import Graphics.Rendering.OpenGL.GL.DataType (
    DataType(..), marshalDataType, unmarshalDataType )
 import Graphics.Rendering.OpenGL.GL.Extensions (
hunk ./Graphics/Rendering/OpenGL/GL/VertexArrays.hs 57
             GetFogCoordArrayType,GetFogCoordArrayStride,
             GetTextureCoordArraySize,GetTextureCoordArrayType,
             GetTextureCoordArrayStride,GetEdgeFlagArrayStride,
+            GetVertexAttributeArrayEnabled,GetVertexAttributeArrayNormalized,
+            GetVertexAttributeArraySize,GetVertexAttributeArrayType,
+            GetVertexAttributeArrayStride,GetCurrentVertexAttribute,
             GetMaxElementsVertices,GetMaxElementsIndices,
             GetClientActiveTexture,GetArrayElementLockFirst,
             GetArrayElementLockCount,GetPrimitiveRestartIndex),
hunk ./Graphics/Rendering/OpenGL/GL/VertexArrays.hs 63
-   getInteger1, getEnum1, getSizei1 )
+   getInteger1, getEnum1, getSizei1,
+   getVertexAttribInteger1, getVertexAttribBoolean1,
+   getVertexAttribEnum1 )
 import Graphics.Rendering.OpenGL.GL.PrimitiveMode ( marshalPrimitiveMode )
 import Graphics.Rendering.OpenGL.GL.BeginEnd ( PrimitiveMode )
 import Graphics.Rendering.OpenGL.GL.StateVar (
hunk ./Graphics/Rendering/OpenGL/GL/VertexArrays.hs 70
    HasGetter(get),
-   GettableStateVar, makeGettableStateVar, StateVar, makeStateVar )
+   GettableStateVar, makeGettableStateVar, StateVar, makeStateVar )   
 import Graphics.Rendering.OpenGL.GL.Texturing.TextureUnit (
    TextureUnit, marshalTextureUnit, unmarshalTextureUnit )
 import Graphics.Rendering.OpenGL.GLU.ErrorsInternal (
hunk ./Graphics/Rendering/OpenGL/GL/VertexArrays.hs 75
    recordInvalidEnum, recordInvalidValue )
+import Graphics.Rendering.OpenGL.GL.VertexSpec ( AttribLocation(..) )
 
 --------------------------------------------------------------------------------
 
hunk ./Graphics/Rendering/OpenGL/GL/VertexArrays.hs 113
    | FogCoordArray
    | SecondaryColorArray
    | MatrixIndexArray
+   | VertexAttributeArray AttribLocation
    deriving ( Eq, Ord, Show )
 
 marshalClientArrayType :: ClientArrayType -> GLenum
hunk ./Graphics/Rendering/OpenGL/GL/VertexArrays.hs 127
    FogCoordArray -> 0x8457
    SecondaryColorArray -> 0x845e
    MatrixIndexArray -> 0x8844
+   VertexAttributeArray _ -> error "marshalClientArrayType: VertexAttributeArray - this shouldn't happen"
 
 -- Hmmm...
 clientArrayTypeToEnableCap :: ClientArrayType -> EnableCap
hunk ./Graphics/Rendering/OpenGL/GL/VertexArrays.hs 141
    FogCoordArray -> CapFogCoordArray
    SecondaryColorArray -> CapSecondaryColorArray
    MatrixIndexArray -> CapMatrixIndexArray
-
+   VertexAttributeArray _ -> error "clientArrayTypeToEnableCap: VertexAttributeArray - this shouldn't happen"
+   
 --------------------------------------------------------------------------------
 
 arrayPointer :: ClientArrayType -> StateVar (VertexArrayDescriptor a)
hunk ./Graphics/Rendering/OpenGL/GL/VertexArrays.hs 159
       makeStateVar
         (do recordInvalidEnum ; return noVertexArrayDescriptor)
         (const recordInvalidEnum)
+   VertexAttributeArray loc -> vertexAttributePointer loc
 
 check :: Bool -> IO () -> IO ()
 check flag val = if flag then val else recordInvalidValue
hunk ./Graphics/Rendering/OpenGL/GL/VertexArrays.hs 320
 
 --------------------------------------------------------------------------------
 
+vertexAttributePointer :: AttribLocation ->StateVar (VertexArrayDescriptor a)
+vertexAttributePointer loc = makeStateVar (getVertexAttributePointer loc) (setVertexAttributePointer loc)
+
+getVertexAttributePointer :: AttribLocation -> IO (VertexArrayDescriptor a)
+getVertexAttributePointer loc <at> (AttribLocation index) = do
+   n <- getVertexAttribInteger1 id                index GetVertexAttributeArraySize 
+   d <- getVertexAttribEnum1    unmarshalDataType index GetVertexAttributeArrayType 
+   s <- getVertexAttribInteger1 fromIntegral      index GetVertexAttributeArrayStride
+   p <- getPointer (VertexAttributeArrayPointer loc)
+   return $ VertexArrayDescriptor n d s p
+
+setVertexAttributePointer :: AttribLocation -> VertexArrayDescriptor a -> IO ()
+setVertexAttributePointer (AttribLocation index) (VertexArrayDescriptor n d s p) =
+   glVertexAttribPointer index n (marshalDataType d) (error "setVertexAttributePointer: normalized") s p
+
 EXTENSION_ENTRY("OpenGL 2.0",glVertexAttribPointer,GLuint -> GLint -> GLenum -> GLboolean -> GLsizei -> Ptr a -> IO ())
 EXTENSION_ENTRY("OpenGL 2.0",glDisableVertexAttribArray,GLuint -> IO ())
 EXTENSION_ENTRY("OpenGL 2.0",glEnableVertexAttribArray,GLuint -> IO ())
hunk ./Graphics/Rendering/OpenGL/GL/VertexArrays.hs 391
    makeStateVar (getClientState arrayType) (setClientState arrayType)
 
 getClientState :: ClientArrayType -> IO Capability
-getClientState = get . makeCapability . clientArrayTypeToEnableCap
+getClientState (VertexAttributeArray loc <at> (AttribLocation index)) = 
+   getVertexAttribBoolean1 unmarshalCapability index GetVertexAttributeArrayEnabled 
+getClientState arrayType = ( get . makeCapability . clientArrayTypeToEnableCap ) arrayType
 
 setClientState :: ClientArrayType -> Capability -> IO ()
hunk ./Graphics/Rendering/OpenGL/GL/VertexArrays.hs 396
+setClientState (VertexAttributeArray (AttribLocation index)) val =
+   if val == Enabled then glEnableVertexAttribArray index else glDisableVertexAttribArray index 
 setClientState arrayType val =
    (if val == Enabled then glEnableClientState else glDisableClientState)
       (marshalClientArrayType arrayType)
hunk ./Graphics/Rendering/OpenGL/GL/VertexArrays.hs 532
    | SelectionBufferPointer
    | WeightArrayPointer
    | MatrixIndexArrayPointer
+   | VertexAttributeArrayPointer AttribLocation
 
 marshalGetPointervPName :: GetPointervPName -> GLenum
 marshalGetPointervPName x = case x of
hunk ./Graphics/Rendering/OpenGL/GL/VertexArrays.hs 548
    SelectionBufferPointer -> 0xdf3
    WeightArrayPointer -> 0x86ac
    MatrixIndexArrayPointer -> 0x8849
-
+   VertexAttributeArrayPointer _ -> 0x8645  
+   
 --------------------------------------------------------------------------------
 
 getPointer :: GetPointervPName -> IO (Ptr a)
hunk ./Graphics/Rendering/OpenGL/GL/VertexArrays.hs 553
+getPointer n <at> (VertexAttributeArrayPointer (AttribLocation index)) = alloca $ \buf -> do
+   glGetVertexAttribPointerv index (marshalGetPointervPName n) buf
+   peek buf
 getPointer n = alloca $ \buf -> do
    glGetPointerv (marshalGetPointervPName n) buf
    peek buf
}
[initial FBO support (EXT_framebuffer_object)
Balazs Komuves <bkomuves <at> gmail.com>**20081203205020] {
hunk ./Graphics/Rendering/OpenGL/GL.hs 45
    module Graphics.Rendering.OpenGL.GL.PerFragment,
    module Graphics.Rendering.OpenGL.GL.Framebuffer,
    module Graphics.Rendering.OpenGL.GL.ReadCopyPixels,
+   module Graphics.Rendering.OpenGL.GL.FBO,
 
    -- * Special Functions
    module Graphics.Rendering.OpenGL.GL.Evaluators,
hunk ./Graphics/Rendering/OpenGL/GL.hs 86
 import Graphics.Rendering.OpenGL.GL.PerFragment
 import Graphics.Rendering.OpenGL.GL.Framebuffer
 import Graphics.Rendering.OpenGL.GL.ReadCopyPixels
+import Graphics.Rendering.OpenGL.GL.FBO
 
 import Graphics.Rendering.OpenGL.GL.Evaluators
 import Graphics.Rendering.OpenGL.GL.Selection
hunk ./Graphics/Rendering/OpenGL/GL/BufferMode.hs 62
      -- front left color buffer is selected.
    | AuxBuffer GLsizei
      -- ^ Only the given auxiliary color buffer no. /i/ is selected.
+   | ColorAttachment' GLsizei 
+     -- ^ Output fragment color to image attached at color attachment point /i/. 
+     -- To be used only with the FBO (framebuffer objects) extension.
+   | DepthAttachment'
+   | StencilAttachment'
    deriving ( Eq, Ord, Show )
 
 marshalBufferMode :: BufferMode -> Maybe GLenum
hunk ./Graphics/Rendering/OpenGL/GL/BufferMode.hs 84
    AuxBuffer i
       | i <= 246  -> Just (0x409 + fromIntegral i)
       | otherwise -> Nothing
-
+   ColorAttachment' i 
+      | i <= 15   -> Just (0x8CE0 + fromIntegral i)
+      | otherwise -> Nothing
+   DepthAttachment'   -> Just 0x8D00
+   StencilAttachment' -> Just 0x8D20
+   
 unmarshalBufferMode :: GLenum -> BufferMode
 unmarshalBufferMode x
    | x == 0x0 = NoBuffers
hunk ./Graphics/Rendering/OpenGL/GL/BufferMode.hs 103
    | x == 0x407 = RightBuffers
    | x == 0x408 = FrontAndBackBuffers
    | 0x409 <= x && x <= 0x4ff = AuxBuffer (fromIntegral x - 0x409)
+   | 0x8CE0 <= x && x <= 0x8CEF = ColorAttachment' (fromIntegral x - 0x8CE0)
+   | x == 0x8D00 = DepthAttachment'
+   | x == 0x8D20 = StencilAttachment'
    | otherwise = error ("unmarshalBufferMode: illegal value " ++ show x)
addfile ./Graphics/Rendering/OpenGL/GL/FBO.hs
hunk ./Graphics/Rendering/OpenGL/GL/FBO.hs 1
+--------------------------------------------------------------------------------
+-- |
+-- Module      :  Graphics.Rendering.OpenGL.GL.FBO
+-- Copyright   :  (c) Balazs Komuves 2008
+-- License     :  BSD-style (see the file libraries/OpenGL/LICENSE)
+-- 
+-- Maintainer  :  bkomuves(plus)hopengl(at)gmail(dot)com
+-- Stability   :  experimental
+-- Portability :  portable
+--
+-- This module corresponds to the  <at> EXT_framebuffer_object <at>  OpenGL extension.
+-- See <http://www.opengl.org/registry/specs/EXT/framebuffer_object.txt>.
+--
+--------------------------------------------------------------------------------
+
+module Graphics.Rendering.OpenGL.GL.FBO (
+   areFBOsSupported,
+   FramebufferAttachment(..), 
+   Renderbuffer(..), renderbufferBinding, defaultRenderbuffer,
+   Framebuffer(..), framebufferBinding, defaultFramebuffer,
+   FramebufferTexture2DTarget(..),
+   framebufferTexture1D, framebufferTexture2D,
+   framebufferTexture3D, framebufferRenderbuffer,
+   RenderbufferPixelBits(..), renderbufferPixelBits,
+   getFramebufferAttachmentParameterInteger1, 
+   getFramebufferAttachmentParameterEnum1,
+   FramebufferStatus(..), checkFramebufferStatus  
+) where
+
+import Foreign.Marshal ( alloca )
+import Foreign.Marshal.Array ( withArray, withArrayLen, peekArray, allocaArray )
+import Foreign.Ptr ( Ptr )
+import Graphics.Rendering.OpenGL.GL.BasicTypes (
+   GLboolean, GLenum, GLint, GLintptr, GLuint, GLsizei, GLsizeiptr )
+import Graphics.Rendering.OpenGL.GL.BufferMode
+import Graphics.Rendering.OpenGL.GL.BufferObjects ( ObjectName(..) )
+import Graphics.Rendering.OpenGL.GL.CoordTrans ( Position(..) , Size(..) )
+import Graphics.Rendering.OpenGL.GL.Extensions (
+   FunPtr, unsafePerformIO, Invoker, getProcAddress )
+import Graphics.Rendering.OpenGL.GL.GLboolean ( unmarshalGLboolean )
+import Graphics.Rendering.OpenGL.GL.PeekPoke ( peek1 )
+import Graphics.Rendering.OpenGL.GL.QueryUtils ( GetPName(..), marshalGetPName, getInteger1 )
+import Graphics.Rendering.OpenGL.GL.StateVar ( 
+   get, GettableStateVar, makeGettableStateVar, StateVar, makeStateVar )
+import Graphics.Rendering.OpenGL.GL.StringQueries ( glExtensions )
+import Graphics.Rendering.OpenGL.GL.Texturing.Objects ( TextureObject(..), textureID )
+import Graphics.Rendering.OpenGL.GL.Texturing.PixelInternalFormat
+import Graphics.Rendering.OpenGL.GL.Texturing.Specification ( Level )
+import Graphics.Rendering.OpenGL.GL.Texturing.TextureTarget (
+   TextureTarget(..), marshalTextureTarget,
+   CubeMapTarget, marshalCubeMapTarget)
+import Graphics.Rendering.OpenGL.GLU.ErrorsInternal ( recordInvalidEnum )
+
+--------------------------------------------------------------------------------
+
+#include "HsOpenGLExt.h"
+
+#define GL_FRAMEBUFFER_EXT                 0x8D40
+#define GL_RENDERBUFFER_EXT                0x8D41
+
+--------------------------------------------------------------------------------
+
+-- | Framebuffer objects (FBOs) are an OpenGL extension, which means
+-- that they are not universally supported.  
+areFBOsSupported :: IO Bool
+areFBOsSupported = do
+   exts <- get glExtensions
+   return $ elem "EXT_framebuffer_object" exts
+   
+--------------------------------------------------------------------------------
+ 
+newtype Renderbuffer = Renderbuffer { renderbufferID :: GLuint }  
+   deriving ( Eq, Ord, Show ) 
+
+newtype Framebuffer = Framebuffer { framebufferID :: GLuint }  
+   deriving ( Eq, Ord, Show ) 
+
+--------------------------------------------------------------------------------
+
+data FramebufferAttachment =
+     ColorAttachment GLsizei 
+   | DepthAttachment
+   | StencilAttachment
+   deriving (Eq,Show)
+
+marshalFramebufferAttachment :: FramebufferAttachment -> GLenum
+marshalFramebufferAttachment attch = case attch of
+   ColorAttachment i
+      | i <= 15   -> (0x8CE0 + fromIntegral i)
+      | otherwise -> error "marshalFramebufferAttachment: ColorAttachment index too large"
+   DepthAttachment   -> 0x8D00
+   StencilAttachment -> 0x8D20
+
+--------------------------------------------------------------------------------
+
+instance ObjectName Renderbuffer where
+   genObjectNames n =
+      allocaArray n $ \buf -> do
+        glGenRenderbuffersEXT (fromIntegral n) buf
+        fmap (map Renderbuffer) $ peekArray n buf
+
+   deleteObjectNames renderbuffers =
+      withArrayLen (map renderbufferID renderbuffers) $
+         glDeleteRenderbuffersEXT . fromIntegral
+
+   isObjectName = fmap unmarshalGLboolean . glIsRenderbufferEXT . renderbufferID
+
+renderbufferBinding :: StateVar (Maybe Renderbuffer)
+renderbufferBinding =
+   makeStateVar
+      (do o <- getInteger1 (Renderbuffer . fromIntegral) GetRenderbufferBinding
+          return $ if o == defaultRenderbuffer then Nothing else Just o)
+      (glBindFramebufferEXT (GL_RENDERBUFFER_EXT) . renderbufferID . (maybe defaultRenderbuffer id))
+
+defaultRenderbuffer :: Renderbuffer
+defaultRenderbuffer = Renderbuffer 0
+
+EXTENSION_ENTRY("GL_EXT_framebuffer_object",glIsRenderbufferEXT,GLuint -> IO GLboolean)
+EXTENSION_ENTRY("GL_EXT_framebuffer_object",glBindRenderbufferEXT,GLenum -> GLuint -> IO ())
+EXTENSION_ENTRY("GL_EXT_framebuffer_object",glDeleteRenderbuffersEXT,GLsizei -> Ptr GLuint -> IO ())
+EXTENSION_ENTRY("GL_EXT_framebuffer_object",glGenRenderbuffersEXT,GLsizei -> Ptr GLuint -> IO ())
+
+--------------------------------------------------------------------------------
+
+renderbufferStorage :: StateVar (PixelInternalFormat, Size)
+renderbufferStorage = makeStateVar getter setter where
+   getter = do
+      ifmt <- getRenderbufferParameterInteger1 
+                 (unmarshalPixelInternalFormat . fromIntegral) 
+                 GetRenderbufferInternalFormat
+      sx   <- getRenderbufferParameterInteger1 fromIntegral GetRenderbufferWidth
+      sy   <- getRenderbufferParameterInteger1 fromIntegral GetRenderbufferHeight
+      return ( ifmt , Size sx sy )
+   setter (ifmt , Size sx sy) = do
+      glRenderbufferStorageEXT
+         GL_RENDERBUFFER_EXT
+         (fromIntegral $ marshalPixelInternalFormat ifmt)
+         sx sy       
+
+EXTENSION_ENTRY("GL_EXT_framebuffer_object",glRenderbufferStorageEXT,GLenum -> GLenum -> GLsizei -> GLsizei -> IO ())
+
+--------------------------------------------------------------------------------
+
+data RenderbufferPixelBits = RenderbufferPixelBits { 
+     renderbufferRedBits :: GLuint
+   , renderbufferGreenBits :: GLuint
+   , renderbufferBlueBits :: GLuint
+   , renderbufferAlphaBits :: GLuint
+   , renderbufferDepthBits :: GLuint
+   , renderbufferStencilBits :: GLuint
+   }
+   deriving (Eq,Show)
+   
+renderbufferPixelBits :: GettableStateVar RenderbufferPixelBits
+renderbufferPixelBits = makeGettableStateVar $ do
+   red <- getRenderbufferParameterInteger1     fromIntegral GetRenderbufferRedSize
+   green <- getRenderbufferParameterInteger1   fromIntegral GetRenderbufferGreenSize
+   blue <- getRenderbufferParameterInteger1    fromIntegral GetRenderbufferBlueSize
+   alpha <- getRenderbufferParameterInteger1   fromIntegral GetRenderbufferAlphaSize
+   depth <- getRenderbufferParameterInteger1   fromIntegral GetRenderbufferDepthSize
+   stencil <- getRenderbufferParameterInteger1 fromIntegral GetRenderbufferStencilSize
+   return $ RenderbufferPixelBits red green blue alpha depth stencil
+      
+--------------------------------------------------------------------------------
+
+getRenderbufferParameterInteger1 :: (GLint -> a) -> GetPName -> IO a
+getRenderbufferParameterInteger1 f n = alloca $ \buf -> do
+   getRenderbufferParameterIntegerv n buf
+   peek1 f buf
+
+getRenderbufferParameterEnum1 :: (GLenum -> a) -> GetPName -> IO a
+getRenderbufferParameterEnum1 f = getRenderbufferParameterInteger1 (f . fromIntegral)
+
+getRenderbufferParameterBoolean1 :: (GLboolean -> a) -> GetPName -> IO a
+getRenderbufferParameterBoolean1 f = getRenderbufferParameterInteger1 (f . fromIntegral)
+
+getRenderbufferParameterIntegerv :: GetPName -> Ptr GLint -> IO ()
+getRenderbufferParameterIntegerv = maybe (const recordInvalidEnum) 
+   (glGetRenderbufferParameterivEXT GL_RENDERBUFFER_EXT) . marshalGetPName
+
+EXTENSION_ENTRY("GL_EXT_framebuffer_object",glGetRenderbufferParameterivEXT,GLenum -> GLenum -> Ptr GLint -> IO ())
+
+--------------------------------------------------------------------------------
+
+instance ObjectName Framebuffer where
+   genObjectNames n =
+      allocaArray n $ \buf -> do
+        glGenFramebuffersEXT (fromIntegral n) buf
+        fmap (map Framebuffer) $ peekArray n buf
+
+   deleteObjectNames framebuffers =
+      withArrayLen (map framebufferID framebuffers) $
+         glDeleteFramebuffersEXT . fromIntegral
+
+   isObjectName = fmap unmarshalGLboolean . glIsFramebufferEXT . framebufferID
+
+framebufferBinding :: StateVar (Maybe Framebuffer)
+framebufferBinding =
+   makeStateVar
+      (do o <- getInteger1 (Framebuffer . fromIntegral) GetFramebufferBinding
+          return $ if o == defaultFramebuffer then Nothing else Just o)
+      (glBindFramebufferEXT (GL_FRAMEBUFFER_EXT) . framebufferID . (maybe defaultFramebuffer id))
+
+defaultFramebuffer :: Framebuffer
+defaultFramebuffer = Framebuffer 0
+
+EXTENSION_ENTRY("GL_EXT_framebuffer_object",glIsFramebufferEXT,GLuint -> IO GLboolean)
+EXTENSION_ENTRY("GL_EXT_framebuffer_object",glBindFramebufferEXT,GLenum -> GLuint -> IO ())
+EXTENSION_ENTRY("GL_EXT_framebuffer_object",glDeleteFramebuffersEXT,GLsizei -> Ptr GLuint -> IO ())
+EXTENSION_ENTRY("GL_EXT_framebuffer_object",glGenFramebuffersEXT,GLsizei -> Ptr GLuint -> IO ())
+
+--------------------------------------------------------------------------------
+
+data FramebufferStatus = 
+     FramebufferComplete
+   | FramebufferIncomplete FramebufferIncomplete
+   | FramebufferUnsupported
+   deriving (Eq,Show)
+
+data FramebufferIncomplete = 
+     IncompleteAttachment
+   | IncompleteMissingAttachment
+   | IncompleteDimensions
+   | IncompleteFormats   
+   | IncompleteDrawBuffer   
+   | IncompleteReadBuffer   
+   deriving (Eq,Show)
+
+checkFramebufferStatus :: IO FramebufferStatus
+checkFramebufferStatus = do
+   i <- glCheckFramebufferStatusEXT GL_FRAMEBUFFER_EXT
+   return $ case unmarshalFramebufferStatus i of
+      Just fbs -> fbs
+      Nothing  -> error "checkFramebufferStatus: should not happen"
+
+marshalFramebufferStatus :: FramebufferStatus -> GLenum
+marshalFramebufferStatus fbs = case fbs of
+   FramebufferComplete -> 0x8CD5
+   FramebufferIncomplete fbi -> marshalFramebufferIncomplete fbi
+   FramebufferUnsupported -> 0x8CDD
+
+marshalFramebufferIncomplete :: FramebufferIncomplete -> GLenum
+marshalFramebufferIncomplete fbi = case fbi of
+   IncompleteAttachment -> 0x8CD6
+   IncompleteMissingAttachment -> 0x8CD7
+   IncompleteDimensions -> 0x8CD9
+   IncompleteFormats -> 0x8CDA
+   IncompleteDrawBuffer -> 0x8CDB
+   IncompleteReadBuffer -> 0x8CDC
+   
+unmarshalFramebufferStatus :: GLenum -> Maybe FramebufferStatus
+unmarshalFramebufferStatus i = case i of
+   0x8CD5 -> Just FramebufferComplete
+   0x8CD6 -> Just $ FramebufferIncomplete IncompleteAttachment
+   0x8CD7 -> Just $ FramebufferIncomplete IncompleteMissingAttachment
+   0x8CD9 -> Just $ FramebufferIncomplete IncompleteDimensions
+   0x8CDA -> Just $ FramebufferIncomplete IncompleteFormats
+   0x8CDB -> Just $ FramebufferIncomplete IncompleteDrawBuffer
+   0x8CDC -> Just $ FramebufferIncomplete IncompleteReadBuffer
+   0x8CDD -> Just FramebufferUnsupported
+   _ -> Nothing
+ 
+EXTENSION_ENTRY("GL_EXT_framebuffer_object",glCheckFramebufferStatusEXT,GLenum -> IO GLenum)
+
+--------------------------------------------------------------------------------
+
+framebufferTexture1D 
+   :: FramebufferAttachment     -- ^ should be one of 'ColorAttachment i', 'DepthAttachment' and 'StencilAttachment'
+   -> Maybe TextureObject  -- ^ should be a 1D texture object 
+   -> Level          -- ^ mipmap level
+   -> IO FramebufferStatus
+framebufferTexture1D attch texobj level = do
+   glFramebufferTexture1DEXT
+      GL_FRAMEBUFFER_EXT 
+      (marshalFramebufferAttachment attch) 
+      (marshalTextureTarget Texture1D) 
+      (maybe 0 textureID texobj) 
+      level   
+   checkFramebufferStatus   
+
+data FramebufferTexture2DTarget =
+     Texture2D'
+   | TextureRectangle' 
+   | TextureCubeMap' CubeMapTarget
+   deriving (Eq,Show)
+
+marshalFramebufferTexture2DTarget :: FramebufferTexture2DTarget -> GLenum
+marshalFramebufferTexture2DTarget tgt = case tgt of
+   Texture2D'        -> marshalTextureTarget Texture2D
+   TextureRectangle' -> marshalTextureTarget TextureRectangle
+   TextureCubeMap' cubemaptgt -> marshalCubeMapTarget cubemaptgt
+   
+framebufferTexture2D 
+   :: FramebufferAttachment    -- ^ should be one of 'ColorAttachment i', 'DepthAttachment' and 'StencilAttachment'
+   -> FramebufferTexture2DTarget  -- Maybe CubeMapTarget 
+   -> Maybe TextureObject 
+   -> Level         -- ^ mipmap level
+   -> IO FramebufferStatus
+framebufferTexture2D attch target texobj level = do
+   glFramebufferTexture2DEXT 
+      GL_FRAMEBUFFER_EXT 
+      (marshalFramebufferAttachment attch) 
+      -- (maybe (marshalTextureTarget Texture2D) marshalCubeMapTarget cubemaptarget)
+      (marshalFramebufferTexture2DTarget target)
+      (maybe 0 textureID texobj) 
+      level   
+   checkFramebufferStatus   
+
+framebufferTexture3D
+   :: FramebufferAttachment    -- ^ should be one of 'ColorAttachment i', 'DepthAttachment' and 'StencilAttachment'
+   -> Maybe TextureObject  -- ^ should be 3D texture object
+   -> Level         -- ^ mipmap level
+   -> GLint         -- ^ z offset
+   -> IO FramebufferStatus
+framebufferTexture3D attch texobj level zoffset = do
+   glFramebufferTexture3DEXT 
+      GL_FRAMEBUFFER_EXT 
+      (marshalFramebufferAttachment attch) 
+      (marshalTextureTarget Texture3D) 
+      (maybe 0 textureID texobj) 
+      level   
+      zoffset
+   checkFramebufferStatus   
+   
+EXTENSION_ENTRY("GL_EXT_framebuffer_object",glFramebufferTexture1DEXT,GLenum -> GLenum -> GLenum -> GLuint -> GLint -> IO ())
+
+EXTENSION_ENTRY("GL_EXT_framebuffer_object",glFramebufferTexture2DEXT,GLenum -> GLenum -> GLenum -> GLuint -> GLint -> IO ())
+
+EXTENSION_ENTRY("GL_EXT_framebuffer_object",glFramebufferTexture3DEXT,GLenum -> GLenum -> GLenum -> GLuint -> GLint -> GLint -> IO ())
+
+--------------------------------------------------------------------------------
+
+framebufferRenderbuffer 
+   :: FramebufferAttachment
+   -> Maybe Renderbuffer
+   -> IO FramebufferStatus
+framebufferRenderbuffer attch renderbuffer = do
+   glFramebufferRenderbufferEXT 
+      GL_FRAMEBUFFER_EXT 
+      (marshalFramebufferAttachment attch) 
+      GL_RENDERBUFFER_EXT
+      (maybe 0 renderbufferID renderbuffer)    
+   checkFramebufferStatus
+   
+EXTENSION_ENTRY("GL_EXT_framebuffer_object",glFramebufferRenderbufferEXT,GLenum -> GLenum -> GLenum -> GLuint -> IO ())
+
+--------------------------------------------------------------------------------
+
+getFramebufferAttachmentParameterInteger1 :: FramebufferAttachment -> (GLint -> a) -> GetPName -> IO a
+getFramebufferAttachmentParameterInteger1 attch f n = alloca $ \buf -> do
+   getFramebufferAttachmentParameterIntegerv attch n buf
+   peek1 f buf
+
+getFramebufferAttachmentParameterEnum1 :: FramebufferAttachment -> (GLenum -> a) -> GetPName -> IO a
+getFramebufferAttachmentParameterEnum1 attch f = 
+   getFramebufferAttachmentParameterInteger1 attch (f . fromIntegral)
+
+getFramebufferAttachmentParameterBoolean1 :: FramebufferAttachment -> (GLboolean -> a) -> GetPName -> IO a
+getFramebufferAttachmentParameterBoolean1 attch f = 
+   getFramebufferAttachmentParameterInteger1 attch (f . fromIntegral)
+
+getFramebufferAttachmentParameterIntegerv :: FramebufferAttachment -> GetPName -> Ptr GLint -> IO ()
+getFramebufferAttachmentParameterIntegerv attch = maybe (const recordInvalidEnum) 
+   (glGetFramebufferAttachmentParameterivEXT GL_FRAMEBUFFER_EXT (marshalFramebufferAttachment attch)) . marshalGetPName
+
+EXTENSION_ENTRY("GL_EXT_framebuffer_object",glGetFramebufferAttachmentParameterivEXT,GLenum -> GLenum -> GLenum -> Ptr GLint -> IO ())
+
+--------------------------------------------------------------------------------
+
+{-
+EXTENSION_ENTRY("GL_EXT_framebuffer_object",glGenerateMipmapEXT,GLenum -> IO ())
+-}
+
+--------------------------------------------------------------------------------
+
+
hunk ./Graphics/Rendering/OpenGL/GL/QueryUtils.hs 27
    getFloat1, getFloat2, getFloat3, getFloat4, getFloatv,
    getDouble1, getDouble2, getDouble4, getDoublev,
    getVertexAttribInteger1, getVertexAttribIntegerv,
-   getVertexAttribEnum1, getVertexAttribBoolean1
+   getVertexAttribEnum1, getVertexAttribBoolean1,
+   marshalGetPName
 ) where
 
 import Foreign.Marshal.Alloc ( alloca )
hunk ./Graphics/Rendering/OpenGL/GL/QueryUtils.hs 435
    | GetDrawBufferN GLsizei
    -- GetWeightArrayBufferBinding
    -- GetVertexAttribArrayBufferBinding
+   
+   | GetFramebufferBinding
+   | GetRenderbufferBinding
+   | GetMaxColorAttachments
+   | GetMaxRenderbufferSize
+   | GetRenderbufferWidth
+   | GetRenderbufferHeight
+   | GetRenderbufferInternalFormat
+   | GetRenderbufferRedSize
+   | GetRenderbufferGreenSize
+   | GetRenderbufferBlueSize
+   | GetRenderbufferAlphaSize
+   | GetRenderbufferDepthSize
+   | GetRenderbufferStencilSize
+   | GetFramebufferAttachmentType
+   | GetFramebufferAttachmentName
+   | GetFramebufferAttachmentTextureLevel
+   | GetFramebufferAttachmentTextureCubemapFace
+   | GetFramebufferAttachmentTexture3DZOffset
 
 marshalGetPName :: GetPName -> Maybe GLenum
 marshalGetPName x = case x of
hunk ./Graphics/Rendering/OpenGL/GL/QueryUtils.hs 845
    -- GetWeightArrayBufferBinding -> Just 0x889e
    -- GetVertexAttribArrayBufferBinding -> Just 0x889f
 
+   GetFramebufferBinding -> Just 0x8CA6  -- use with 'getInteger1'
+   GetRenderbufferBinding -> Just 0x8CA7
+   GetMaxColorAttachments -> Just 0x8CDF 
+   GetMaxRenderbufferSize -> Just 0x84E8
+   GetRenderbufferWidth -> Just 0x8D42  -- use with 'getRenderbufferParameter*'
+   GetRenderbufferHeight -> Just 0x8D43
+   GetRenderbufferInternalFormat -> Just 0x8D44
+   GetRenderbufferRedSize -> Just 0x8D50
+   GetRenderbufferGreenSize -> Just 0x8D51
+   GetRenderbufferBlueSize -> Just 0x8D52
+   GetRenderbufferAlphaSize -> Just 0x8D53
+   GetRenderbufferDepthSize -> Just 0x8D54
+   GetRenderbufferStencilSize -> Just 0x8D55
+   GetFramebufferAttachmentType -> Just 0x8CD0  -- use with 'getFramebufferAttachmentParameter*'
+   GetFramebufferAttachmentName -> Just 0x8CD1
+   GetFramebufferAttachmentTextureLevel -> Just 0x8CD2
+   GetFramebufferAttachmentTextureCubemapFace -> Just 0x8CD3
+   GetFramebufferAttachmentTexture3DZOffset -> Just 0x8CD4
+
 --------------------------------------------------------------------------------
 
 -- 0x3000 through 0x3FFF are reserved for clip planes
hunk ./Graphics/Rendering/OpenGL/GL/QueryUtils.hs 1036
 EXTENSION_ENTRY("OpenGL 2.0",glGetVertexAttribfv,GLuint -> GLenum -> Ptr GLfloat  -> IO ())
 EXTENSION_ENTRY("OpenGL 2.0",glGetVertexAttribiv,GLuint -> GLenum -> Ptr GLint    -> IO ())
 
+--------------------------------------------------------------------------------
+
hunk ./Graphics/Rendering/OpenGL/GL/Texturing/Objects.hs 17
 --------------------------------------------------------------------------------
 
 module Graphics.Rendering.OpenGL.GL.Texturing.Objects (
-   TextureObject(TextureObject), textureBinding,
+   TextureObject(TextureObject), textureID, textureBinding,
    textureResident, areTexturesResident,
    TexturePriority, texturePriority, prioritizeTextures
 ) where
hunk ./Graphics/Rendering/OpenGL/GL/Texturing/PixelInternalFormat.hs 86
    | CompressedSRGBAlpha
    | CompressedSLuminance
    | CompressedSLuminanceAlpha
+   | StencilIndex1
+   | StencilIndex4
+   | StencilIndex8
+   | StencilIndex16
    deriving ( Eq, Ord, Show )
 
 marshalPixelInternalFormat :: PixelInternalFormat -> GLint
hunk ./Graphics/Rendering/OpenGL/GL/Texturing/PixelInternalFormat.hs 154
    CompressedSRGBAlpha -> 0x8c49
    CompressedSLuminance -> 0x8c4a
    CompressedSLuminanceAlpha -> 0x8c4b
+   StencilIndex1 -> 0x8D46  -- used with Framebuffer Objects
+   StencilIndex4 -> 0x8D47
+   StencilIndex8 -> 0x8D48
+   StencilIndex16 -> 0x8D49
 
 -- *sigh* The OpenGL API is sometimes a bit creative in its usage of types...
 marshalPixelInternalFormat' :: PixelInternalFormat -> GLenum
hunk ./Graphics/Rendering/OpenGL/GL/Texturing/PixelInternalFormat.hs 225
    | x == 0x8c49 = CompressedSRGBAlpha
    | x == 0x8c4a = CompressedSLuminance
    | x == 0x8c4b = CompressedSLuminanceAlpha
+   -- stencil for framebuffer objects
+   | x == 0x8D46 = StencilIndex1
+   | x == 0x8D47 = StencilIndex4
+   | x == 0x8D48 = StencilIndex8
+   | x == 0x8D49 = StencilIndex16
    -- legacy values
    | x == 1 = Luminance'
    | x == 2 = LuminanceAlpha'
hunk ./Graphics/Rendering/OpenGL/GLU/ErrorsInternal.hs 43
    | GL_StackUnderflow
    | GL_OutOfMemory
    | GL_TableTooLarge
+   | GL_InvalidFramebufferOperation
 
 gl_marshalErrorCode :: GL_ErrorCode -> GLenum
 gl_marshalErrorCode x = case x of
hunk ./Graphics/Rendering/OpenGL/GLU/ErrorsInternal.hs 55
    GL_StackUnderflow -> 0x504
    GL_OutOfMemory -> 0x505
    GL_TableTooLarge -> 0x8031
+   GL_InvalidFramebufferOperation -> 0x506
 
 --------------------------------------------------------------------------------
 -- See comment above
hunk ./Graphics/Rendering/OpenGL/GLU/ErrorsInternal.hs 119
    | TableTooLarge
    | TesselatorError
    | NURBSError
+   | InvalidFramebufferOperation
    deriving ( Eq, Ord, Show )
 
 unmarshalErrorCategory :: GLenum -> ErrorCategory
hunk ./Graphics/Rendering/OpenGL/GLU/ErrorsInternal.hs 133
    | isTableTooLarge c    = TableTooLarge
    | isTesselatorError c  = TesselatorError
    | isNURBSError c       = NURBSError
+   | isInvalidFramebufferOperation c = InvalidFramebufferOperation 
    | otherwise = error "unmarshalErrorCategory"
 
 isInvalidEnum :: GLenum -> Bool
hunk ./Graphics/Rendering/OpenGL/GLU/ErrorsInternal.hs 178
    marshalNurbsError NurbsError1 <= c &&
    c <= marshalNurbsError NurbsError37
 
+isInvalidFramebufferOperation :: GLenum -> Bool
+isInvalidFramebufferOperation c =
+   c == gl_marshalErrorCode GL_InvalidFramebufferOperation
+   
 --------------------------------------------------------------------------------
 
 -- The returned error string is statically allocated, so peekCString
hunk ./OpenGL.cabal 39
 	Graphics.Rendering.OpenGL.GL.DisplayLists,
 	Graphics.Rendering.OpenGL.GL.Evaluators,
 	Graphics.Rendering.OpenGL.GL.Feedback,
+	Graphics.Rendering.OpenGL.GL.FBO,
 	Graphics.Rendering.OpenGL.GL.FlushFinish,
 	Graphics.Rendering.OpenGL.GL.Fog,
 	Graphics.Rendering.OpenGL.GL.Framebuffer,
}
[more FBO support/fixes
Balazs Komuves <bkomuves <at> gmail.com>**20081217120454] {
hunk ./Graphics/Rendering/OpenGL/GL/FBO.hs 18
 
 module Graphics.Rendering.OpenGL.GL.FBO (
    areFBOsSupported,
-   FramebufferAttachment(..), 
-   Renderbuffer(..), renderbufferBinding, defaultRenderbuffer,
+   FramebufferAttachment(..), maxColorAttachments,
+   Renderbuffer(..), renderbufferBinding, renderbufferStorage,
+   defaultRenderbuffer, maxRenderbufferSize,
    Framebuffer(..), framebufferBinding, defaultFramebuffer,
    FramebufferTexture2DTarget(..),
    framebufferTexture1D, framebufferTexture2D,
hunk ./Graphics/Rendering/OpenGL/GL/FBO.hs 25
    framebufferTexture3D, framebufferRenderbuffer,
+   framebufferAttachment, FramebufferAttachment'(..),
+   framebufferAttachmentTextureLevel,
+   framebufferAttachmentTextureCubeMapFace,
+   framebufferAttachmentTexture3DZOffset,
    RenderbufferPixelBits(..), renderbufferPixelBits,
hunk ./Graphics/Rendering/OpenGL/GL/FBO.hs 30
-   getFramebufferAttachmentParameterInteger1, 
-   getFramebufferAttachmentParameterEnum1,
    FramebufferStatus(..), checkFramebufferStatus  
 ) where
 
hunk ./Graphics/Rendering/OpenGL/GL/FBO.hs 54
 import Graphics.Rendering.OpenGL.GL.Texturing.Specification ( Level )
 import Graphics.Rendering.OpenGL.GL.Texturing.TextureTarget (
    TextureTarget(..), marshalTextureTarget,
-   CubeMapTarget, marshalCubeMapTarget)
+   CubeMapTarget, marshalCubeMapTarget, unmarshalCubeMapTarget )
 import Graphics.Rendering.OpenGL.GLU.ErrorsInternal ( recordInvalidEnum )
 
 --------------------------------------------------------------------------------
hunk ./Graphics/Rendering/OpenGL/GL/FBO.hs 84
 --------------------------------------------------------------------------------
 
 data FramebufferAttachment =
-     ColorAttachment GLsizei 
+     ColorAttachment GLenum
    | DepthAttachment
    | StencilAttachment
    deriving (Eq,Show)
hunk ./Graphics/Rendering/OpenGL/GL/FBO.hs 97
    DepthAttachment   -> 0x8D00
    StencilAttachment -> 0x8D20
 
+-- | The largest 'ColorAttachment' value allowed is  <at> n-1 <at> , where 
+--  <at> n = get maxColorAttachments$
+maxColorAttachments :: GettableStateVar GLuint
+maxColorAttachments = makeGettableStateVar $ do
+   getInteger1 fromIntegral GetMaxColorAttachments
+
 --------------------------------------------------------------------------------
 
 instance ObjectName Renderbuffer where
hunk ./Graphics/Rendering/OpenGL/GL/FBO.hs 122
    makeStateVar
       (do o <- getInteger1 (Renderbuffer . fromIntegral) GetRenderbufferBinding
           return $ if o == defaultRenderbuffer then Nothing else Just o)
-      (glBindFramebufferEXT (GL_RENDERBUFFER_EXT) . renderbufferID . (maybe defaultRenderbuffer id))
+      (glBindRenderbufferEXT (GL_RENDERBUFFER_EXT) . renderbufferID . (maybe defaultRenderbuffer id))
 
 defaultRenderbuffer :: Renderbuffer
 defaultRenderbuffer = Renderbuffer 0
hunk ./Graphics/Rendering/OpenGL/GL/FBO.hs 127
 
+maxRenderbufferSize :: GettableStateVar GLsizei
+maxRenderbufferSize = makeGettableStateVar $ do
+   getInteger1 fromIntegral GetMaxRenderbufferSize
+
 EXTENSION_ENTRY("GL_EXT_framebuffer_object",glIsRenderbufferEXT,GLuint -> IO GLboolean)
 EXTENSION_ENTRY("GL_EXT_framebuffer_object",glBindRenderbufferEXT,GLenum -> GLuint -> IO ())
 EXTENSION_ENTRY("GL_EXT_framebuffer_object",glDeleteRenderbuffersEXT,GLsizei -> Ptr GLuint -> IO ())
hunk ./Graphics/Rendering/OpenGL/GL/FBO.hs 184
    getRenderbufferParameterIntegerv n buf
    peek1 f buf
 
+{-
 getRenderbufferParameterEnum1 :: (GLenum -> a) -> GetPName -> IO a
 getRenderbufferParameterEnum1 f = getRenderbufferParameterInteger1 (f . fromIntegral)
 
hunk ./Graphics/Rendering/OpenGL/GL/FBO.hs 190
 getRenderbufferParameterBoolean1 :: (GLboolean -> a) -> GetPName -> IO a
 getRenderbufferParameterBoolean1 f = getRenderbufferParameterInteger1 (f . fromIntegral)
+-}
 
 getRenderbufferParameterIntegerv :: GetPName -> Ptr GLint -> IO ()
 getRenderbufferParameterIntegerv = maybe (const recordInvalidEnum) 
hunk ./Graphics/Rendering/OpenGL/GL/FBO.hs 282
 
 --------------------------------------------------------------------------------
 
+data FramebufferAttachment' = 
+     None'
+   | TextureObject' TextureObject 
+   | Renderbuffer' Renderbuffer
+   deriving (Eq,Show)
+   
+framebufferAttachment :: GettableStateVar FramebufferAttachment'
+framebufferAttachment = makeGettableStateVar $ do
+   typ <- getInteger1 fromIntegral GetFramebufferAttachmentObjectType
+   nam <- getInteger1 fromIntegral GetFramebufferAttachmentObjectName
+   return $ case typ of
+      0 -> None'
+      0x1702 -> TextureObject' (TextureObject nam)   -- 0x1702 = GL_TEXTURE
+      GL_RENDERBUFFER_EXT -> Renderbuffer' (Renderbuffer nam)
+                  
+framebufferAttachmentTextureLevel :: GettableStateVar GLuint
+framebufferAttachmentTextureLevel = makeGettableStateVar $ do
+   getInteger1 fromIntegral GetFramebufferAttachmentTextureLevel
+
+framebufferAttachmentTextureCubeMapFace :: GettableStateVar CubeMapTarget
+framebufferAttachmentTextureCubeMapFace = makeGettableStateVar $ do
+   getInteger1 
+      (unmarshalCubeMapTarget . fromIntegral) 
+      GetFramebufferAttachmentTextureCubeMapFace
+
+framebufferAttachmentTexture3DZOffset :: GettableStateVar GLuint
+framebufferAttachmentTexture3DZOffset = makeGettableStateVar $ do
+   getInteger1 fromIntegral GetFramebufferAttachmentTexture3DZOffset
+
+--------------------------------------------------------------------------------
+
 framebufferTexture1D 
    :: FramebufferAttachment     -- ^ should be one of 'ColorAttachment i', 'DepthAttachment' and 'StencilAttachment'
    -> Maybe TextureObject  -- ^ should be a 1D texture object 
hunk ./Graphics/Rendering/OpenGL/GL/FBO.hs 400
    getFramebufferAttachmentParameterIntegerv attch n buf
    peek1 f buf
 
+{-
 getFramebufferAttachmentParameterEnum1 :: FramebufferAttachment -> (GLenum -> a) -> GetPName -> IO a
 getFramebufferAttachmentParameterEnum1 attch f = 
    getFramebufferAttachmentParameterInteger1 attch (f . fromIntegral)
hunk ./Graphics/Rendering/OpenGL/GL/FBO.hs 408
 getFramebufferAttachmentParameterBoolean1 :: FramebufferAttachment -> (GLboolean -> a) -> GetPName -> IO a
 getFramebufferAttachmentParameterBoolean1 attch f = 
    getFramebufferAttachmentParameterInteger1 attch (f . fromIntegral)
+-}
 
 getFramebufferAttachmentParameterIntegerv :: FramebufferAttachment -> GetPName -> Ptr GLint -> IO ()
 getFramebufferAttachmentParameterIntegerv attch = maybe (const recordInvalidEnum) 
hunk ./Graphics/Rendering/OpenGL/GL/QueryUtils.hs 449
    | GetRenderbufferAlphaSize
    | GetRenderbufferDepthSize
    | GetRenderbufferStencilSize
-   | GetFramebufferAttachmentType
-   | GetFramebufferAttachmentName
+   | GetFramebufferAttachmentObjectType
+   | GetFramebufferAttachmentObjectName
    | GetFramebufferAttachmentTextureLevel
hunk ./Graphics/Rendering/OpenGL/GL/QueryUtils.hs 452
-   | GetFramebufferAttachmentTextureCubemapFace
+   | GetFramebufferAttachmentTextureCubeMapFace
    | GetFramebufferAttachmentTexture3DZOffset
 
 marshalGetPName :: GetPName -> Maybe GLenum
hunk ./Graphics/Rendering/OpenGL/GL/QueryUtils.hs 858
    GetRenderbufferAlphaSize -> Just 0x8D53
    GetRenderbufferDepthSize -> Just 0x8D54
    GetRenderbufferStencilSize -> Just 0x8D55
-   GetFramebufferAttachmentType -> Just 0x8CD0  -- use with 'getFramebufferAttachmentParameter*'
-   GetFramebufferAttachmentName -> Just 0x8CD1
+   GetFramebufferAttachmentObjectType -> Just 0x8CD0  -- use with 'getFramebufferAttachmentParameter*'
+   GetFramebufferAttachmentObjectName -> Just 0x8CD1
    GetFramebufferAttachmentTextureLevel -> Just 0x8CD2
hunk ./Graphics/Rendering/OpenGL/GL/QueryUtils.hs 861
-   GetFramebufferAttachmentTextureCubemapFace -> Just 0x8CD3
+   GetFramebufferAttachmentTextureCubeMapFace -> Just 0x8CD3
    GetFramebufferAttachmentTexture3DZOffset -> Just 0x8CD4
 
 --------------------------------------------------------------------------------
hunk ./Graphics/Rendering/OpenGL/GL/Texturing/TextureTarget.hs 18
 
 module Graphics.Rendering.OpenGL.GL.Texturing.TextureTarget (
    TextureTarget(..), marshalTextureTarget, marshalProxyTextureTarget,
-   CubeMapTarget(..), marshalCubeMapTarget
+   CubeMapTarget(..), marshalCubeMapTarget, unmarshalCubeMapTarget
 ) where
 
 import Graphics.Rendering.OpenGL.GL.BasicTypes ( GLenum )
hunk ./Graphics/Rendering/OpenGL/GL/Texturing/TextureTarget.hs 70
    TextureCubeMapNegativeY -> 0x8518
    TextureCubeMapPositiveZ -> 0x8519
    TextureCubeMapNegativeZ -> 0x851a
+
+unmarshalCubeMapTarget :: GLenum -> CubeMapTarget
+unmarshalCubeMapTarget x = case x of
+   0x8515 -> TextureCubeMapPositiveX
+   0x8516 -> TextureCubeMapNegativeX
+   0x8517 -> TextureCubeMapPositiveY
+   0x8518 -> TextureCubeMapNegativeY
+   0x8519 -> TextureCubeMapPositiveZ
+   0x851a -> TextureCubeMapNegativeZ
}

Context:

[TAG GHC 6.8.1 release
Ian Lynagh <igloo <at> earth.li>**20071110011104] 
[TAG 2.2.1.1 release
Ian Lynagh <igloo <at> earth.li>**20071110010954] 
[Bump version number
Ian Lynagh <igloo <at> earth.li>**20071027124805] 
[Specify build-type: Configure
Duncan Coutts <duncan <at> haskell.org>**20071018173137] 
[--configure-option and --ghc-option are now provided by Cabal
Ross Paterson <ross <at> soi.city.ac.uk>**20070604115936] 
[Remove Makefile and package.conf.in (used in the old GHC build system)
Ian Lynagh <igloo <at> earth.li>**20070524145614] 
[add includes: field
Simon Marlow <simonmar <at> microsoft.com>**20070517094912] 
[Make configure fail if the package cannot be built
Ian Lynagh <igloo <at> earth.li>**20070430111732] 
[TAG GHC 6.6.1 release
Ian Lynagh <igloo <at> earth.li>**20070428195851] 
[TAG 2.2.1 release
Ian Lynagh <igloo <at> earth.li>**20070428195655] 
[TAG GHC 6.6.1 release
Ian Lynagh <igloo <at> earth.li>**20070424113929] 
[TAG Version 2.2.1
Ian Lynagh <igloo <at> earth.li>**20070424113831] 
[Bump version to 2.2.1
Ian Lynagh <igloo <at> earth.li>**20070422195057] 
[Follow Cabal changes in Setup.*hs
Ian Lynagh <igloo <at> earth.li>**20070418121330] 
[Fix -Wall warnings
Ian Lynagh <igloo <at> earth.li>**20070411012221] 
[Make Setup.hs suitable for building in a GHC tree
Ian Lynagh <igloo <at> earth.li>**20070407174116] 
[Importing hs_OpenGL_getProcAddres must use ccall instead of CALLCONV
sven.panne <at> aedion.de**20070313174609
 
 Patch provided by shelarcy <at> gmail.com
] 
[README about building from darcs
Ross Paterson <ross <at> soi.city.ac.uk>**20070218110200] 
[Note that we support OpenGL 2.1 now
sven.panne <at> aedion.de**20070101125021] 
[Completed implementation of drawBuffers
sven.panne <at> aedion.de**20061130133951] 
[Made drawBuffers a full-blown StateVar (getter not yet implemented)
sven.panne <at> aedion.de**20061130132401] 
[Refactored (un)marshalling of modelview indices, fixing an off-by-two bug on the way
sven.panne <at> aedion.de**20061130132135] 
[Changed the type of a few implementation limits to GLsizei for consistency reasons
sven.panne <at> aedion.de**20061130123956] 
[Added current raster secondary color query
sven.panne <at> aedion.de**20061129125402] 
[Added sRGB textures
sven.panne <at> aedion.de**20061129121705] 
[Added pixel buffer objects
sven.panne <at> aedion.de**20061129093054] 
[Made 'uniform' a 'StateVar' to allow queries, too
sven.panne <at> aedion.de**20061122130106] 
[Added missing Storable instance for FogCoord1
sven.panne <at> aedion.de**20061122123656] 
[Added vertexProgramTwoSide and vertexProgramPointSize
sven.panne <at> aedion.de**20061121120200] 
[Do not return trailing NUL in shader string queries
sven.panne <at> aedion.de**20061115151908] 
[Make Eq/Ord/Show/ObjectName superclasses of Shader
sven.panne <at> aedion.de**20061112140430] 
[Added utility function 'majorMinor' to easily parse OpenGL's version strings
sven.panne <at> aedion.de**20061112131225] 
[Extended the set of possible types for vertex attributes and uniform variables
sven.panne <at> aedion.de**20061110131951] 
[Distributed shader-related stuff to the right modules
sven.panne <at> aedion.de**20061110122648] 
[Updated Haddock module headers (now OpenGL 2.1 support, API is stable)
sven.panne <at> aedion.de**20061110101454] 
[Partial implementation of vertex attributes/uniform variables
sven.panne <at> aedion.de**20061109143842] 
[Added a few missing OpenGL 2.0 features and prepared GLSL variable access
sven.panne <at> aedion.de**20061108144500] 
[Added Haddock comments for GLSL implementation limits
sven.panne <at> aedion.de**20061107140514] 
[Completed handling of shaders and programs
sven.panne <at> aedion.de**20061106151311] 
[Implement almost all shader/program related API entries
sven.panne <at> aedion.de**20061103141002] 
[More GLSL functionality, mainly queries plus some cleanup
sven.panne <at> aedion.de**20061102134107] 
[Added shading-related queries
sven.panne <at> aedion.de**20061102133821] 
[Added missing import
sven.panne <at> aedion.de**20061102094212] 
[Added basic Shader/Program functionality
sven.panne <at> aedion.de**20061101210232] 
[First steps towards GLSL support
sven.panne <at> aedion.de**20061101193753] 
[Added autoconf magic for GLchar/GLintptr/GLsizeiptr
sven.panne <at> aedion.de**20061101183122] 
[Slightly improved the NURBS API
sven.panne <at> aedion.de**20061012114037] 
[includes -> install-includes
Ross Paterson <ross <at> soi.city.ac.uk>**20060829123744] 
[exclude Setup.hs even if not building package
Ross Paterson <ross <at> soi.city.ac.uk>**20060825222701] 
[exclude Setup.hs from build
Ross Paterson <ross <at> soi.city.ac.uk>**20060824183533] 
[add boilerplate Setup.hs
Ross Paterson <ross <at> soi.city.ac.uk>**20060824115102] 
[add files used by configure
Ross Paterson <ross <at> soi.city.ac.uk>**20060518174356] 
[TAG Initial conversion from CVS complete
John Goerzen <jgoerzen <at> complete.org>**20060112154136] 
Patch bundle hash:
ba3ba67c931bccd977a97544c9743c3fe8cdd24e
_______________________________________________
HOpenGL mailing list
HOpenGL <at> haskell.org
http://www.haskell.org/mailman/listinfo/hopengl
Corey O'Connor | 17 Dec 2008 18:58
Picon

Re: EXT_framebuffer_object support.

Excellent stuff! I like having the framebuffer texture functions check
the status as well. That's a handy addition.
So how do we get your patch into the mainline repo? I'd hate to have
another person duplicate the same work again.

Cheers,
Corey O'Connor

On Wed, Dec 17, 2008 at 4:19 AM, Balazs Komuves <bkomuves <at> gmail.com> wrote:
>
> Hello,
>
> Actually I did the exact same thing. My "EXT_framebuffer_object" support is
> fairly complete,
> and I tried to match the existing style, but it is not really tested apart
> from a simple example.
> I also attached a patch which adds support for using Vertex Attributes in
> Vertex Arrays (which
> is standard OpenGL, not an extension, but was missing), but that one is
> completely untested;
> and also a bugfix (uniformLocation and friends).
>
> Balazs
>
> On Wed, Dec 17, 2008 at 9:32 AM, Corey O'Connor <coreyoconnor <at> gmail.com>
> wrote:
>>
>> Hello all,
>> I searched for current efforts on adding EXT_framebuffer_object
>> support to HOpenGL but was unable to locate anything.
>> I've added the very beginnings of EXT_framebuffer_object support.
>> Attached (in theory) is the current patch.
>> I've only added the bare minimum required to render to a 2D texture
>> and am not sure if the style matches the current style.
>>
>> If the patch was stripped from this email the changes can be pulled from:
>>    http://www.tothepowerofdisco.com/repo/OpenGL
>>
>> Cheers,
>> Corey O'Connor
>>
>> _______________________________________________
>> HOpenGL mailing list
>> HOpenGL <at> haskell.org
>> http://www.haskell.org/mailman/listinfo/hopengl
>>
>
>
> _______________________________________________
> HOpenGL mailing list
> HOpenGL <at> haskell.org
> http://www.haskell.org/mailman/listinfo/hopengl
>
>
Balazs Komuves | 17 Dec 2008 20:12
Picon

Re: EXT_framebuffer_object support.


I think we should have some testing and code review before trying to merge it with the
official repository (there is a reason I did not publicised this before, though the FBO stuff
is fairly new). For example I just discovered two (very minor) bugs by trying to generate
Haddock documentation. The API isn't set into stone either; I hope it's reasonable
enough, but some changes may be beneficial.

After that, well, Sven Panne reads this mailing list, and he is the maintainer. It would be
nice to hear his opinion.

Balazs

On Wed, Dec 17, 2008 at 6:58 PM, Corey O'Connor <coreyoconnor <at> gmail.com> wrote:
Excellent stuff! I like having the framebuffer texture functions check
the status as well. That's a handy addition.
So how do we get your patch into the mainline repo? I'd hate to have
another person duplicate the same work again.

Cheers,
Corey O'Connor



_______________________________________________
HOpenGL mailing list
HOpenGL <at> haskell.org
http://www.haskell.org/mailman/listinfo/hopengl
Corey O'Connor | 17 Dec 2008 22:12
Picon

Re: EXT_framebuffer_object support.

On Wed, Dec 17, 2008 at 11:12 AM, Balazs Komuves <bkomuves <at> gmail.com> wrote:
>
> I think we should have some testing and code review before trying to merge
> it with the
> official repository (there is a reason I did not publicised this before,
> though the FBO stuff
> is fairly new). For example I just discovered two (very minor) bugs by
> trying to generate
> Haddock documentation. The API isn't set into stone either; I hope it's
> reasonable
> enough, but some changes may be beneficial.

Hm. I certainly agree that testing and API review is required for
release. However I'd prefer other developers to have easy access to
these patches through a main development repository than not. If API
stability is a concern with the main repository then I suggest having
two repositories: One for development and another for stable use.

Cheers,
Corey

> On Wed, Dec 17, 2008 at 6:58 PM, Corey O'Connor <coreyoconnor <at> gmail.com>
> wrote:
>>
>> Excellent stuff! I like having the framebuffer texture functions check
>> the status as well. That's a handy addition.
>> So how do we get your patch into the mainline repo? I'd hate to have
>> another person duplicate the same work again.
>>
>> Cheers,
>> Corey O'Connor
>>
>>
>
>
Balazs Komuves | 18 Dec 2008 16:18
Picon

Re: EXT_framebuffer_object support.


Having a separate public development repo for the experimental stuff is
a good idea. Maybe we can ask for project space on the code.haskell.org
community server? They have all the infrastructure in place already.

Balazs


Hm. I certainly agree that testing and API review is required for
release. However I'd prefer other developers to have easy access to
these patches through a main development repository than not. If API
stability is a concern with the main repository then I suggest having
two repositories: One for development and another for stable use.

Cheers,
Corey

> On Wed, Dec 17, 2008 at 6:58 PM, Corey O'Connor <coreyoconnor <at> gmail.com>
> wrote:
>>
>> Excellent stuff! I like having the framebuffer texture functions check
>> the status as well. That's a handy addition.
>> So how do we get your patch into the mainline repo? I'd hate to have
>> another person duplicate the same work again.
>>
>> Cheers,
>> Corey O'Connor
>>
>>
>
>

_______________________________________________
HOpenGL mailing list
HOpenGL <at> haskell.org
http://www.haskell.org/mailman/listinfo/hopengl

Gmane