diff --git a/Graphics/OpenGLES.hs b/Graphics/OpenGLES.hs
--- a/Graphics/OpenGLES.hs
+++ b/Graphics/OpenGLES.hs
@@ -1,9 +1,13 @@
 -- | OpenGL ES (ES for Embed Systems) 2.0 and 3.0
--- <http://www.khronos.org/opengles/sdk/docs/reference_cards/OpenGL-ES-2_0-Reference-card.pdf>
--- <http://www.khronos.org/files/opengles3-quick-reference-card.pdf>
 -- 
--- ANGLE: OpenGL ES 2.0 backend for Windows.
--- <http://code.google.com/p/angleproject/>
+-- - <https://www.khronos.org/registry/gles/specs/3.1/es_spec_3.1.withchanges.pdf OpenGL® ES Version 3.1 (June 4, 2014) [PDF]>
+-- - <http://www.khronos.org/opengles/sdk/docs/man31/ OpenGL ES 3.1 Manual>
+-- - <http://www.khronos.org/files/opengles3-quick-reference-card.pdf OpenGL ES 3.0 Quick Reference [PDF]>
+-- - <http://www.khronos.org/opengles/sdk/docs/man3/ OpenGL ES 3.0 Manual>
+-- - <http://www.khronos.org/opengles/sdk/docs/reference_cards/OpenGL-ES-2_0-Reference-card.pdf OpenGL ES 2.0 Quick Reference [PDF]>
+-- - <http://www.khronos.org/opengles/sdk/docs/man/ OpenGL ES 2.0 Manual>
+-- - <http://code.google.com/p/angleproject/ ANGLE>
+-- OpenGL ES backend for Windows.
 
 module Graphics.OpenGLES (
   module Control.Future,
diff --git a/Graphics/OpenGLES/Buffer.hs b/Graphics/OpenGLES/Buffer.hs
--- a/Graphics/OpenGLES/Buffer.hs
+++ b/Graphics/OpenGLES/Buffer.hs
@@ -1,12 +1,15 @@
-{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE ScopedTypeVariables#-}
+{-# LANGUAGE MultiParamTypeClasses #-}
+{-# LANGUAGE FlexibleInstances,KindSignatures,TypeFamilies,OverlappingInstances #-}
 module Graphics.OpenGLES.Buffer (
   -- * Buffer
   -- ** Constructing Mutable Buffers
   Buffer,
-  glNewBuffer, glLoadList, glLoadBS,
+  GLArray,
+  GLSource(..),
+  glLoad, glReload, glUnsafeRead, glModify, glMap,
   -- ** Updating Mutable Buffers
-  unsafeObtainStorableArray, withStorableArraySize,
-  glRenewBuffer, glReloadList, glReloadBS,
+  withStorableArraySize,
   BufferUsage, app2gl, app2glDyn, app2glStream,
   gl2app, gl2appDyn, gl2appStream, gl2gl, gl2glDyn, gl2glStream,
   -- ** Raw Buffer Operations
@@ -25,8 +28,10 @@
   -- | /3+ | GL_NV_copy_buffer/ glCopyBufferSubDataNV
   copyBufferSubData,
   BufferSlot, array_buffer, element_array_buffer,
+  -- | /ES 3+/
   pixel_pack_buffer, pixel_unpack_buffer,
   uniform_buffer, transform_feedback_buffer,
+  -- | /3+ or GL_NV_copy_buffer/
   copy_read_buffer, copy_write_buffer
   ) where
 import Control.Applicative
@@ -38,47 +43,184 @@
 import Data.IORef
 import Graphics.OpenGLES.Base
 import Graphics.OpenGLES.Internal
-import Foreign
+import Graphics.OpenGLES.Env
+import Foreign hiding (newArray)
 
 -- ** Constructing Mutable Buffers
 
-glNewBuffer :: forall a. Storable a => BufferUsage -> Int -> GL (Buffer a)
-glNewBuffer usage elems = do
-	array <- newArray_ (0, elems)
-	glo <- newBuffer
-	bufferData array_buffer usage (elems * sizeOf (undefined :: a)) nullPtr
-	Buffer usage glo <$> newIORef array
+type GLArray a = StorableArray Int a
 
-glLoadList
-	:: forall a. Storable a => BufferUsage
-	-> (Int, Int)
-	-> [a]
-	-> GL (Buffer a)
-glLoadList usage ix xs = do
-	array <- newListArray ix xs
-	glo <- newBuffer
-	withStorableArraySize array $ \size ptr ->
-		bufferData array_buffer usage size ptr
-	Buffer usage glo <$> newIORef array
+type family Content a x :: *
+type instance Content Int x = x
+type instance Content B.ByteString x = x
+type instance Content [a] x = a
+type instance Content ([a],Int) x = a
+type instance Content (GLArray a) x = a
 
-glLoadBS :: forall a. Storable a => BufferUsage -> B.ByteString -> GL (Buffer a)
-glLoadBS usage bs@(B.PS foreignPtr offset len) = do
-	let fp | offset == 0 = foreignPtr
-	       | otherwise = case B.copy bs of (B.PS f _ _) -> f
-	let elems = (len `div` sizeOf (undefined :: a))
-	let array = StorableArray 0 (elems-1) elems (castForeignPtr fp)
-	glo <- newBuffer
-	withForeignPtr fp $ \ptr ->
-		bufferData array_buffer usage len ptr
-	Buffer usage glo <$> newIORef array
+class (Storable b, b ~ Content a b) => GLSource a b where
+	makeAref :: a -> GL (Either (GLArray (Content a b)) Int)
+	makeWriter :: a -> (Ptr (Content a b) -> GL (), Int)
 
+instance Storable b => GLSource Int b where
+	makeAref = return . Right
+	makeWriter len = (\ptr -> B.memset (castPtr ptr) 0
+		(fromIntegral $ len * sizeOf (undefined :: b))
+			>> return (), len)
+instance Storable a => GLSource ([a], Int) a where
+	makeAref (xs, len) = Left <$> newListArray (0, len) (cycle xs)
+	makeWriter (xs, len) = (\ptr -> pokeArray ptr xs, len)
+instance Storable a => GLSource [a] a where
+	makeAref xs = Left <$> newListArray (0, length xs) xs
+	makeWriter xs = (\ptr -> pokeArray ptr xs, length xs)
+instance Storable b => GLSource B.ByteString b where
+	makeAref bs@(B.PS foreignPtr offset len) = do
+		let fp | offset == 0 = foreignPtr
+		       | otherwise = case B.copy bs of (B.PS f _ _) -> f
+		let elems = (len `div` sizeOf (undefined :: b))
+		let array = StorableArray 0 (elems-1) elems (castForeignPtr fp)
+		return (Left array)
+	makeWriter (B.PS fp offset len) = (\dst ->
+		withForeignPtr fp $ \src ->
+			B.memcpy (castPtr dst) (advancePtr (castPtr src) offset) len
+		, len `div` sizeOf (undefined :: b))
+instance Storable a => GLSource (GLArray a) a where
+	makeAref = return . Left
+	makeWriter sa@(StorableArray _ _ len fp) =
+		(\dst -> withForeignPtr fp $ \src ->
+			B.memcpy (castPtr dst) (castPtr src)
+			(len * sizeOf (undefined :: a))
+		, len)
+--instance GLSource (Buffer a) a where
+--	makeAref (Buffer aref glo) = return . Left =<< go =<< readIORef aref
+--	where
+--		go (Left)
+--		go (Right) 
 
--- ** Updating Mutable Buffers
 
+-- |
+-- Create and initialize a 'Buffer' storage on GPU working memory.
+-- 
+-- - Int → /O(1)/
+-- New Buffer with specified number of elements initialized to zeros.
+-- - ([a], Int) → /O(n)/
+-- New Buffer made of given list upto n th element.
+-- - [a] → /O(n)/
+-- New Buffer made of given list. Same as (xs, length xs)
+-- - 'ByteString' → /head O(1) otherwise O(n)/
+-- New Buffer from 'ByteString'. Might be copied when necessary.
+-- - 'GLArray' → __Unsafe__ /O(1)/
+-- Use passed 'StorableArray' as client-side Buffer.
+-- 
+-- > glLoad app2gl (10::Int) :: GL (Buffer Vec4)
+-- > glLoad app2gl ([V2 1 1],4::Int) :: GL (Buffer Vec2)
+-- > glLoad app2gl uv :: GL (Buffer (V2 Word8))
+-- > glLoad app2gl bs :: GL (Buffer Float)
+-- > glLoad app2gl (model :: GLArray Model) :: GL (Buffer Model)
+glLoad :: forall a b. GLSource a b => BufferUsage -> a -> GL (Buffer b)
+glLoad usage src = do
+	aref <- newIORef =<< makeAref src
+	Buffer aref <$> newBuffer (do
+		array <- readIORef aref
+		case array of
+			Left sa ->
+				withStorableArraySize sa (bufferData array_buffer usage)
+			Right elems ->
+				bufferData array_buffer usage (elems * unit) nullPtr
+		) where unit = sizeOf (undefined :: b)
+	-- TODO BufferArchive
 
-unsafeObtainStorableArray :: Buffer a -> IO (StorableArray Int a)
-unsafeObtainStorableArray (Buffer _ _ arr) = readIORef arr
+newBuffer init = newGLO glGenBuffers glDeleteBuffers
+	(\i -> glBindBuffer 0x8892 i >> init) -- GL_ARRAY_BUFFER
 
+newArrayLen elems unit = do
+	sa@(StorableArray _ _ _ fp) <- newArray_ (0, elems - 1)
+	withForeignPtr fp $ \dst ->
+		B.memset (castPtr dst) 0 (fromIntegral $ elems * unit)
+	return sa
+
+glReload :: forall a b. GLSource a b => Buffer b -> Int -> a -> GL ()
+glReload buf@(Buffer aref glo) offsetIx src = do
+	bindBuffer array_buffer buf
+	aref' <- readIORef aref
+	let unit = sizeOf (undefined :: b)
+	let (fillSubArray, size') = makeWriter src
+	let size = size' * unit
+	if hasES3 then do
+		ptr <- mapBufferRange array_buffer (offsetIx * unit) size
+			(map_write_bit + map_invalidate_range_bit + map_unsynchronized_bit)
+		fillSubArray ptr
+		unmapBuffer array_buffer
+		case aref' of Left (StorableArray _ _ len _) ->
+				writeIORef aref (Right (len * unit))
+	else do
+		sa@(StorableArray _ _ len fp) <- case aref' of
+			Left array -> return array
+			Right elems -> newArrayLen elems unit
+		withForeignPtr fp $ \p -> do
+			let ptr = advancePtr p (offsetIx * unit)
+			fillSubArray ptr
+			bufferSubData array_buffer (offsetIx * unit) size ptr
+		writeIORef aref (Left sa)
+
+
+glUnsafeRead :: forall a. Storable a => Buffer a -> (Int, Int) -> GL (GLArray a)
+glUnsafeRead buf@(Buffer aref glo) (offsetIx, len) = do
+	bindBuffer array_buffer buf
+	array <- readIORef aref
+	case array of
+		Left (StorableArray s e l fp) -> -- unsafe!
+			return (StorableArray s e l fp)
+		Right elems -> do
+			sa <- newArrayLen (min len (elems - offsetIx)) unit
+			if hasES3 then do
+				src <- mapBufferRange array_buffer (offsetIx * unit) (len * unit)
+					(map_read_bit {- + map_unsynchronized_bit-})
+				withStorableArray sa $ \dst ->
+					B.memcpy (castPtr dst) src (len * unit)
+				unmapBuffer array_buffer
+				writeIORef aref (Left sa) -- backup
+				return sa
+			else return sa
+	where unit = sizeOf (undefined :: a)
+
+glModify :: forall a. Storable a => Buffer a -> (Int, Int) -> (GLArray a -> GL ()) -> GL ()
+glModify buf@(Buffer aref glo) (offsetIx, len) f = do
+	bindBuffer array_buffer buf
+	if hasES3 then do
+		a <- readIORef aref
+		let elems = case a of
+			Right elems -> elems
+			Left (StorableArray _ _ elems _) -> elems 
+		ptr <- mapBufferRange array_buffer 0 (len * unit)
+					(map_read_bit + map_write_bit {- + map_unsynchronized_bit-})
+		fp <- newForeignPtr_ ptr
+		f $ StorableArray 0 (elems-1) elems fp
+		unmapBuffer array_buffer
+		writeIORef aref (Right elems)
+	else do
+		a <- readIORef aref
+		case a of 
+			Left sa -> do
+				f sa
+				withStorableArraySize sa (bufferSubData array_buffer 0)
+			Right elems -> do
+				sa <- newArrayLen elems unit
+				f sa
+				withStorableArraySize sa (bufferSubData array_buffer 0)
+	where unit = sizeOf (undefined :: a)
+
+glMap :: Storable a => (a -> GL a) -> Buffer a -> (Int, Int) -> GL ()
+glMap f buffer offLen = glModify buffer offLen $
+	\(StorableArray _ _ len fp) ->
+ 	withForeignPtr fp $ \ptr ->
+		sequence_
+			[ peekElemOff ptr i >>= f >>= pokeElemOff ptr i
+			| i <- [0..len-1] ]
+
+
+-- ** Updating Mutable Buffers
+
+
 withStorableArraySize
 	:: forall i e a. Storable e
 	=> StorableArray i e -> (Int -> Ptr e -> IO a) -> IO a
@@ -86,33 +228,11 @@
 	withForeignPtr fp (f size)
 	where size = n * sizeOf (undefined :: e)
 
--- Performance hint http://www.opentk.com/node/1930
-glRenewBuffer :: forall a. Storable a => BufferUsage -> Int -> Buffer a -> GL ()
-glRenewBuffer usage elems buf@(Buffer _ _ ref) = do
-	array <- newArray_ (0, elems)
-	bindBuffer array_buffer buf
-	bufferData array_buffer usage (elems * sizeOf (undefined :: a)) nullPtr
-	writeIORef ref array
-
-glReloadList :: forall a. Storable a =>
-	BufferUsage -> (Int, Int) -> [a] -> Buffer a -> GL ()
-glReloadList usage ix xs buf@(Buffer _ _ ref) = do
-	array <- newListArray ix xs
-	bindBuffer array_buffer buf
-	withStorableArraySize array $ \size ptr -> do
-		bufferData array_buffer usage size ptr
-	writeIORef ref array
+-- hasMapBufferRange = hasES3
+-- GL_NV_map_buffer_range	5devices	2%
+-- GL_EXT_map_buffer_range	2devices	1%
 
-glReloadBS :: forall a. Storable a =>
-	BufferUsage -> B.ByteString -> Buffer a -> GL ()
-glReloadBS usage bs@(B.PS foreignPtr offset len) buf = do
-	let fp | offset == 0 = foreignPtr
-	       | otherwise = case B.copy bs of (B.PS f _ _) -> f
-	let elems = (len `div` sizeOf (undefined :: a))
-	let array = StorableArray 0 (elems-1) elems (castForeignPtr fp)
-	withForeignPtr fp $ \ptr -> do
-		--bufferData array_buffer usage 0 nullPtr
-		bufferData array_buffer usage len ptr
+-- Performance hint http://www.opentk.com/node/1930
 
 
 -- ** Buffer Slots
@@ -141,17 +261,17 @@
 -- ** Raw Buffer Operations
 
 bindBuffer :: BufferSlot -> Buffer a -> GL ()
-bindBuffer (BufferSlot target) (Buffer _ glo _) =
-	glBindBuffer target . fst =<< readIORef glo
+bindBuffer (BufferSlot target) (Buffer _ glo) =
+	glBindBuffer target =<< getObjId glo
 
 bindBufferRange :: BufferSlot -> GLuint -> Buffer a -> Int -> Int -> GL ()
-bindBufferRange (BufferSlot t) index (Buffer _ glo _) offset size = do
-	buf <- fmap fst $ readIORef glo
+bindBufferRange (BufferSlot t) index (Buffer _ glo) offset size = do
+	buf <- getObjId glo
 	glBindBufferRange t index buf offset size
 
 bindBufferBase :: BufferSlot -> GLuint -> Buffer a -> GL ()
-bindBufferBase (BufferSlot t) index (Buffer _ glo _) = do
-	glBindBufferBase t index . fst =<< readIORef glo
+bindBufferBase (BufferSlot t) index (Buffer _ glo) = do
+	glBindBufferBase t index =<< getObjId glo
 
 bufferData :: BufferSlot -> BufferUsage -> Int -> Ptr a -> GL ()
 bufferData (BufferSlot target) (BufferUsage usage) size ptr =
diff --git a/Graphics/OpenGLES/Core.hs b/Graphics/OpenGLES/Core.hs
--- a/Graphics/OpenGLES/Core.hs
+++ b/Graphics/OpenGLES/Core.hs
@@ -118,6 +118,7 @@
 		Just _ -> nop
 		Nothing -> waitGLThread
 	waitGLThread
+	writeIORef frameCounter 0
 	putStrLn "Rendering has stopped."
 
 --destroyGL :: IO ()
@@ -127,7 +128,9 @@
 endFrameGL = withGL go >>= waitFuture >> nop
 	where go = do
 		readIORef drawOrExit >>= \case
-			Just eglSwapBuffer -> eglSwapBuffer
+			Just eglSwapBuffer -> do
+				eglSwapBuffer
+				modifyIORef frameCounter (+1)
 			Nothing -> myThreadId >>= killThread
 
 runGL :: GL () -> IO ()
@@ -166,7 +169,13 @@
 nop :: Monad m => m ()
 nop = return ()
 
+glFrameCount :: IO Int
+glFrameCount = readIORef frameCounter
 
+glFlipping :: IO Bool
+glFlipping = fmap odd glFrameCount
+
+
 -- * Drawing
 
 -- |
@@ -192,12 +201,12 @@
 	-> GL Bool
 glDraw (DrawMode mode) prog@(Program pobj _ _ _) setState unifs
 		(VertexArray (vao, setVA)) (VertexPicker picker) = do
-	glUseProgram . fst =<< readIORef pobj
+	glUseProgram =<< getObjId pobj
 	sequence setState
 	sequence unifs
 	case extVAO of
 		Nothing -> setVA
-		Just (_, bind, _) -> readIORef vao >>= bind . fst
+		Just (_, bind, _) -> getObjId vao >>= bind
 	--glValidate prog
 	picker mode
 
@@ -251,7 +260,7 @@
 -- program can execute given the current OpenGL state.
 glValidate :: Program p -> GL String
 glValidate prog = alloca $ \intptr -> do
-	(pid, _) <- readIORef $ programGLO prog
+	pid <- getObjId $ programGLO prog
 	glValidateProgram pid
 	glGetProgramiv pid c_info_log_length intptr
 	len <- fmap fromIntegral $ peek intptr
@@ -330,7 +339,7 @@
 	glo <- case extVAO of
 		Nothing -> return (error "GLO not used")
 		Just (gen, bind, del) ->
-			newGLO gen bind del <* setVA
+			newGLO gen del (\i-> bind i >> setVA)
 	return $ VertexArray (glo, setVA)
 
 
diff --git a/Graphics/OpenGLES/Framebuffer.hs b/Graphics/OpenGLES/Framebuffer.hs
new file mode 100644
--- /dev/null
+++ b/Graphics/OpenGLES/Framebuffer.hs
@@ -0,0 +1,137 @@
+{-# LANGUAGE ExistentialQuantification #-}
+{-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE MultiParamTypeClasses #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+module Graphics.OpenGLES.Framebuffer where
+import Control.Applicative
+import Control.Monad (when)
+import Data.IORef
+import Foreign
+import Graphics.OpenGLES.Base
+import Graphics.OpenGLES.Env (hasES3)
+import Graphics.OpenGLES.Internal
+import Graphics.OpenGLES.PixelFormat
+import Linear.Vect
+
+-- |
+-- New Renderbuffer with specified sample count and dimentions.
+glRenderbuffer :: forall a b. InternalFormat a b => Int32 -> GL (V2 Int32) -> GL (Renderbuffer b)
+glRenderbuffer sample askSize = do
+	let (_, _, internalformat) = ifmt ([] :: [(a,b)])
+	unsafeRenderbuffer sample askSize internalformat
+
+unsafeRenderbuffer :: Int32 -> GL (V2 Int32) -> GLenum -> GL (Renderbuffer a)
+unsafeRenderbuffer samples askSize internalformat = do
+	let sample = if hasES3 then samples else 0
+	dim <- newIORef undefined
+	Renderbuffer samples internalformat dim
+		<$> (newGLO glGenRenderbuffers glDeleteRenderbuffers $ \rb -> do
+			glBindRenderbuffer 0x8D41 rb
+			win@(V2 w h) <- askSize
+			writeIORef dim win
+			case sample of
+				0 -> glRenderbufferStorage 0x8D41 internalformat w h
+				_ -> glRenderbufferStorageMultisample 0x8D41 samples internalformat w h
+			-- XXX restore content on EGL_CONTEXT_LOST if possible
+			)
+
+instance Attachable Renderbuffer a where
+	glAttachToFramebuffer attachment (Renderbuffer _ _ dim glo) maxDims = do
+		rb <- getObjId glo
+		V2 w h <- readIORef dim
+		modifyIORef maxDims (\(V2 mw mh)-> V2 (max w mw) (max h mh))
+		glFramebufferRenderbuffer 0x8D40 attachment 0x8D41 rb
+
+--instance Attachable Texture a where
+--	glAttachToFramebuffer attachment (Texture textgt ktx glo) maxDims = do
+--		tex <- getObjId glo
+--		let V2 w h = ktx...
+--		modifyIORef maxDims (\(V2 mw mh)-> V2 (max w mw) (max h mh))
+--		case textgt of
+			-- Texture2D
+			-- CubeMap
+--			glFramebufferTexture2D 0x8D40 attachment textgt tex level
+			-- Texture3D
+			-- Texture2DArray
+--			glFramebufferTextureLayer 0x8D40 attachment tex level layer
+
+newtype DepthStencil = DepthStencil (IORef (V2 Int32) -> GL ())
+data CR = forall a c. (Attachable a c, ColorRenderable c) => CR (a c)
+
+colorOnly :: DepthStencil
+colorOnly = DepthStencil (const $ return ())
+
+depthImage :: (Attachable a d, DepthRenderable d) => a d -> DepthStencil
+depthImage = DepthStencil . glAttachToFramebuffer 0x8D00
+
+stencilImage :: (Attachable a s, StencilRenderable s) => a s -> DepthStencil
+stencilImage = DepthStencil . glAttachToFramebuffer 0x8D20
+
+depthStencil :: (Attachable a r, DepthRenderable r, StencilRenderable r) => a r -> DepthStencil
+depthStencil = DepthStencil . glAttachToFramebuffer 0x821A
+
+-- | New 'Framebuffer' from specified 'ColorRenderable' and 'DepthStencil'
+glFramebuffer :: [CR] -> DepthStencil -> GL Framebuffer
+glFramebuffer colours (DepthStencil runds) = do
+	maxDims <- newIORef (V2 0 0)
+	Framebuffer maxDims
+		<$> (newGLO glGenFramebuffers glDeleteFramebuffers $ \fb -> do
+			glBindFramebuffer 0x8D40 fb
+			sequence_ $ zipWith (go maxDims) [0x8CE0..] colours
+			runds maxDims
+			)
+	where go maxDims attachment (CR cr) =
+		glAttachToFramebuffer attachment cr maxDims
+
+bindFb :: Framebuffer -> GL ()
+bindFb (Framebuffer _ glo) =
+	getObjId glo >>= glBindFramebuffer 0x8D40
+
+-- XXX maybe slow (untested)
+withFb :: Framebuffer -> GL a -> GL a
+withFb fb io = do
+	-- GL_FRAMEBUFFER_BINDING
+	fb' <- alloca $ \p -> glGetIntegerv 0x8CA6 p >> peek p
+	bindFb fb
+	result <- io
+	glBindFramebuffer 0x8D40 (fromIntegral fb')
+	return result
+
+-- XXX maybe slow (untested)
+getViewport :: GL (V4 Int32)
+getViewport = allocaArray 4 $ \p -> do
+	glGetIntegerv 0x0BA2 p -- GL_VIEWPORT
+	[x,y,w,h] <- peekArray 4 p
+	return $ V4 x y w h
+
+-- |
+-- Cliping current framebuffer. Note that origin is left-bottom.
+setViewport :: V4 Int32 -> GL ()
+setViewport (V4 x y w h) = glViewport x y w h
+
+withViewport :: V4 Int32 -> GL a -> GL a
+withViewport vp io = do
+	old <- getViewport
+	setViewport vp
+	result <- io
+	setViewport old
+	return result
+
+-- XXX maybe slow (untested)
+getDepthRange :: GL (V2 Float)
+getDepthRange = allocaArray 2 $ \p -> do
+	glGetFloatv 0x0B70 p -- GL_DEPTH_RANGE
+	[n,f] <- peekArray 2 p
+	return $ V2 n f
+
+setDepthRange :: V2 Float -> GL ()
+setDepthRange (V2 near far) = glDepthRangef near far
+
+withDepthRange :: V2 Float -> GL a -> GL a
+withDepthRange dr io = do
+	old <- getDepthRange
+	setDepthRange dr
+	result <- io
+	setDepthRange old
+	return result
+
diff --git a/Graphics/OpenGLES/Internal.hs b/Graphics/OpenGLES/Internal.hs
--- a/Graphics/OpenGLES/Internal.hs
+++ b/Graphics/OpenGLES/Internal.hs
@@ -26,6 +26,9 @@
 -- bufferArchive = unsafePerformIO $ newIORef []
 -- addCompiledProgramResources
 
+frameCounter :: IORef Int
+frameCounter = unsafePerformIO $ newIORef 0
+
 -- ** Logging
 
 errorQueue :: Chan String
@@ -55,66 +58,121 @@
 showError :: String -> GL Bool
 showError location = do
 	putStrLn location -- tmp
-	getError >>= maybe (return False)
-		(\err -> do
-			glLog ("E " ++ location ++ ": " ++ show err)
-			return True )
+	getError >>= maybe (return False) (\err -> do
+		glLog ("E " ++ location ++ ": " ++ show err)
+		return True )
 
 -- ** GL Object management
+type GLO = IORef GLObj
+data GLObj = GLObj GLuint (GL GLObj) (ForeignPtr GLuint)
 
-type GLO = IORef (GLuint, ForeignPtr GLuint)
+getObjId glo = fmap go (readIORef glo)
+	where go (GLObj i _ _) = i
 
 instance Show GLO where
-	show ref = show . unsafePerformIO $ readIORef ref
+	show = show . unsafePerformIO . getObjId
 
 newGLO
 	:: (GLsizei -> Ptr GLuint -> GL ())
-	-> (GLuint -> GL ())
 	-> (GLsizei -> Ptr GLuint -> GL ())
+	-> (GLuint -> GL ())
 	-> GL GLO
-newGLO gen bind del = do
+newGLO gen del init = do
 	ref <- newIORef undefined
-	genObj ref gen bind del
+	writeIORef ref =<< genObj gen del init
+	-- addToGLOMS ref
 	return ref
 
 -- | genObj glo glGenBuffers glDeleteBuffers
 genObj
-	:: GLO
+	:: (GLsizei -> Ptr GLuint -> GL ())
 	-> (GLsizei -> Ptr GLuint -> GL ())
 	-> (GLuint -> GL ())
-	-> (GLsizei -> Ptr GLuint -> GL ())
-	-> GL GLuint
-genObj ref genObjs bindObj delObjs = do
+	-> GL GLObj
+genObj genObjs delObjs initObj = do
 	fp <- mallocForeignPtr
 	withForeignPtr fp $ \ptr -> do
 		genObjs 1 ptr
 		showError "genObj"
 		obj <- peek ptr
-		writeIORef ref (obj, fp)
 		addForeignPtrFinalizer fp $ do
-			(obj, _) <- readIORef ref
+			-- XXX check whether context is valud or not
 			with obj $ \ptr -> do
 				delObjs 1 ptr
 				void $ showError "delObj"
-		bindObj obj
-		return obj
+		initObj obj
+		return $ GLObj obj (genObj genObjs delObjs initObj) fp
 
 
+-- ** Types
+-- VertexArray
+-- 2.0
+newtype HalfFloat = HalfFloat Word16 deriving (Num,Storable)
+newtype FixedFloat = FixedFloat Int32 deriving (Num,Storable)
+-- 3.0
+newtype Int2_10x3 = Int210x3 Int32 deriving (Num,Storable)
+newtype Word2_10x3 = Word2_10x3 Int32 deriving (Num,Storable)
+
+-- Renderbuffer
+-- 2.0
+newtype Word4444 = Word4444 Word16 deriving (Num,Storable)
+newtype Word5551 = Word5551 Word16 deriving (Num,Storable)
+newtype Word565 = Word565 Word16 deriving (Num,Storable)
+-- 3.0
+newtype Word10f11f11f = Word10f11f11f Word32 deriving (Num,Storable)
+newtype Word5999 = Word5999 Word32 deriving (Num,Storable)
+newtype Word24_8 = Word24_8 Word32 deriving (Num,Storable)
+newtype FloatWord24_8 = FloatWord24_8 (Float, Word32)
+
+class GLType a where
+	glType :: m a -> Word32
+
+instance GLType Int8 where glType _ = 0x1400
+instance GLType Word8 where glType _ = 0x1401
+instance GLType Int16 where glType _ = 0x1402
+instance GLType Word16 where glType _ = 0x1403
+instance GLType Int32 where glType _ = 0x1404
+instance GLType Word32 where glType _ = 0x1405
+
+instance GLType Float where glType _ = 0x1406
+instance GLType HalfFloat where glType _ = 0x140B
+instance GLType FixedFloat where glType _ = 0x140C
+instance GLType Int2_10x3 where glType _ = 0x8D9F
+instance GLType Word2_10x3 where glType _ = 0x8368
+
+instance GLType Word4444 where glType _ = 0x8033
+instance GLType Word5551 where glType _ = 0x8034
+instance GLType Word565 where glType _ = 0x8363
+instance GLType Word10f11f11f where glType _ = 0x8C3B
+instance GLType Word5999 where glType _ = 0x8C3E
+instance GLType Word24_8 where glType _ = 0x84FA
+instance GLType FloatWord24_8 where glType _ = 0x8DAD
+
+r,rg,rgb,rgba,r_integer,rg_integer,rgb_integer,rgba_integer,
+	depth_component,depth_stencil :: GLenum
+rgb = 0x1907
+rgba = 0x1908
+depth_component = 0x1902
+
+r = 0x1903
+rg = 0x8227
+rg_integer = 0x8228
+r_integer = 0x8D94
+rgb_integer = 0x8D98
+rgba_integer = 0x8D99
+depth_stencil = 0x84F9
+
+
 -- ** Buffer
 
--- forall s. ST s a -> a
--- Buffer usage [GLtype] stride id (latestArray, isBufferSynced)
--- DoubleBuffer BufferUsage GLO GLO (IORef (Bool, GLArray a, GLArray a))
-data Buffer a =
-	Buffer BufferUsage GLO (IORef (StorableArray Int a))
+-- Buffer usage id (latestArray or length)
+data Buffer a = Buffer 	(IORef (Either (StorableArray Int a) Int)) GLO
+-- DoubleBuffer GLO GLO (IORef (GLArray a))
 
 newtype BufferUsage = BufferUsage GLenum
 
 newtype BufferSlot = BufferSlot GLenum
 
-newBuffer = newGLO glGenBuffers (glBindBuffer 0x8892) glDeleteBuffers
-
-
 -- ** DrawMode
 
 newtype DrawMode = DrawMode GLenum
@@ -235,7 +293,7 @@
 		vars <- getActiveVariables pid
 		putStrLn . show $ vars
 		fp <- newForeignPtr nullPtr (glDeleteProgram pid)
-		writeIORef (programGLO prog) (pid, fp)
+		writeIORef (programGLO prog) (GLObj pid (error "not impl: Program implicit recompilation") fp)
 		let msg = "Successfully linked " ++ progname ++ "!" ++ info'
 		glLog msg
 		progressLogger (numShaders + 1) msg Nothing
@@ -398,28 +456,7 @@
 -- (glo, init)
 newtype VertexArray p = VertexArray (GLO, GL ())
 
-newtype HalfFloat = HalfFloat Word16 deriving (Num,Read,Show,Storable)
-newtype FixedFloat = FixedFloat Int32 deriving (Num,Read,Show,Storable)
-newtype Int10x3_2 = Int10x3_2 Int32 deriving (Num,Read,Show,Storable)
-newtype Word10x3_2 = Word10x3_2 Int32 deriving (Num,Read,Show,Storable)
 
-class GLType a where
-	glType :: m a -> Word32
-
-instance GLType Int8 where glType _ = 0x1400
-instance GLType Word8 where glType _ = 0x1401
-instance GLType Int16 where glType _ = 0x1402
-instance GLType Word16 where glType _ = 0x1403
-instance GLType Int32 where glType _ = 0x1404
-instance GLType Word32 where glType _ = 0x1405
-
-instance GLType Float where glType _ = 0x1406
-instance GLType HalfFloat where glType _ = 0x140B
-instance GLType FixedFloat where glType _ = 0x140C
-instance GLType Int10x3_2 where glType _ = 0x8D9F
-instance GLType Word10x3_2 where glType _ = 0x8368
-
-
 -- ** Vertex Picker
 
 newtype VertexPicker = VertexPicker (GLenum -> GL Bool)
@@ -427,11 +464,11 @@
 class VertexIx a where
 	vxix :: m a -> (GLenum, GLint)
 instance VertexIx Word8 where
-	vxix = const (0x1401, 1)
+	vxix _ = (0x1401, 1)
 instance VertexIx Word16 where
-	vxix = const (0x1403, 2)
+	vxix _ = (0x1403, 2)
 instance VertexIx Word32 where
-	vxix = const (0x1405, 4)
+	vxix _ = (0x1405, 4)
 
 
 -- ** Draw Operation
@@ -447,4 +484,18 @@
 drawQueue = unsafePerformIO newChan
 {-# NOINLINE drawQueue #-}
 
+
+-- ** Framebuffer
+
+data Framebuffer = Framebuffer (IORef (V2 GLsizei)) GLO
+data Renderbuffer a = Renderbuffer GLint GLenum (IORef (V2 GLsizei)) GLO
+
+class Attachable a b where
+	glAttachToFramebuffer :: GLenum -> a b -> IORef (V2 GLsizei) -> GL ()
+
+defaultFramebuffer :: Framebuffer
+defaultFramebuffer = unsafePerformIO $ do
+	glo <- newIORef $ GLObj 0 undefined undefined
+	dummy <- newIORef undefined
+	return $ Framebuffer dummy glo
 
diff --git a/Graphics/OpenGLES/PixelFormat.hs b/Graphics/OpenGLES/PixelFormat.hs
new file mode 100644
--- /dev/null
+++ b/Graphics/OpenGLES/PixelFormat.hs
@@ -0,0 +1,283 @@
+{-# LANGUAGE CPP #-}
+{-# LANGUAGE MultiParamTypeClasses #-}
+{-# LANGUAGE FunctionalDependencies #-}
+{-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE DataKinds #-}
+{-# LANGUAGE KindSignatures #-}
+{-# LANGUAGE TypeFamilies #-}
+{-# LANGUAGE TypeOperators #-}
+{-# LANGUAGE UndecidableInstances #-}
+module Graphics.OpenGLES.PixelFormat where
+import Data.Proxy
+import GHC.TypeLits
+import Data.Int
+import Data.Word
+import Graphics.OpenGLES.Internal
+import Graphics.OpenGLES.Base
+import Linear.Vect
+--import Linear
+
+-- Texture Only Sized Internal Formats
+data R8snorm
+data Rg8snorm
+data Rgb8snorm
+data Rgba8snorm
+data Srgb8
+data R16f
+data Rg16f
+data Rgb16f
+data Rgba16f
+data R32f
+data Rg32f
+data Rgb32f
+data Rgba32f
+data B10fG11fR11f
+data E5bgr9
+data Rgb8i
+data Rgb8ui
+data Rgb16i
+data Rgb16ui
+data Rgb32i
+data Rgb32ui
+
+-- Color Renderable Sized Internal Formats
+data R8
+data Rg8
+data Rgb8
+data Rgb565
+data Rgba4
+data Rgb5a1
+data Rgba8
+data A2bgr10
+data A2bgr10ui
+data Srgb8a8
+data R8i
+data R8ui
+data R16i
+data R16ui
+data R32i
+data R32ui
+data Rg8i
+data Rg8ui
+data Rg16i
+data Rg16ui
+data Rg32i
+data Rg32ui
+data Rgba8i
+data Rgba8ui
+data Rgba16i
+data Rgba16ui
+data Rgba32i
+data Rgba32ui
+
+-- Depth/Stencil Renderable Sized Internal Formats
+data Depth16
+data Depth24
+data Depth32f
+data Depth24Stencil8
+data Depth32fStencil8
+data Stencil8 -- optional
+
+-- Effective internal formats which do not correspond to GL constants
+data Luminance8Alpha8
+data Luminance8
+data Alpha8
+
+
+class InternalFormat a b | b -> a where
+	ifmt :: p (a, b) -> (GLenum,GLenum,GLenum)
+
+class ExternalFormat a b where
+	efmt :: p (a, b) -> (GLenum,GLenum,GLenum)
+
+class InternalFormat a b => ES2Format a b where
+	es2fmt :: p (a, b) -> (GLenum,GLenum,GLenum)
+	es2fmt x = case ifmt x of
+		(format, typ, _) -> (format, typ, format)
+
+#define PixelFormat(_dim, _type, _tag, _format, _internal_fmt) \
+instance InternalFormat (_dim _type) _tag where \
+	{-# INLINE ifmt #-}; \
+	ifmt _ = (_format,glType ([] :: [_type]),_internal_fmt) \
+
+PixelFormat(, Int8, R8snorm, r, 0x8F94)
+PixelFormat(V2, Int8, Rg8snorm, rg, 0x8F95)
+PixelFormat(V3, Int8, Rgb8snorm, rgb, 0x8F96)
+PixelFormat(V4, Int8, Rgba8snorm, rgba, 0x8F97)
+PixelFormat(V3, Word8, Srgb8, rgb, 0x8C41)
+PixelFormat(, HalfFloat, R16f, r, 0x822D)
+PixelFormat(V2, HalfFloat, Rg16f, rg, 0x822F)
+PixelFormat(V3, HalfFloat, Rgb16f, rgb, 0x881B)
+PixelFormat(V4, HalfFloat, Rgba16f, rgba, 0x881A)
+PixelFormat(, Float, R32f, r, 0x822E)
+PixelFormat(V2, Float, Rg32f, rg, 0x8230)
+PixelFormat(V3, Float, Rgb32f, rgb, 0x8815)
+PixelFormat(V4, Float, Rgba32f, rgba, 0x8814)
+PixelFormat(, Word10f11f11f, B10fG11fR11f, rgb, 0x8C3A)
+PixelFormat(, Word5999, E5bgr9, rgb, 0x8C3D)
+PixelFormat(V3, Int8, Rgb8i, rgb_integer, 0x8D8F)
+PixelFormat(V3, Word8, Rgb8ui, rgb_integer, 0x8D7D)
+PixelFormat(V3, Int16, Rgb16i, rgb_integer, 0x8D89)
+PixelFormat(V3, Word16, Rgb16ui, rgb_integer, 0x8D77)
+PixelFormat(V3, Int32, Rgb32i, rgb_integer, 0x8D83)
+PixelFormat(V3, Word32, Rgb32ui, rgb_integer, 0x8D71)
+
+PixelFormat(, Word8, R8, r, 0x8229)
+PixelFormat(V2, Word8, Rg8, rg, 0x822B)
+PixelFormat(V3, Word8, Rgb8, rgb, 0x8051)
+PixelFormat(, Word565, Rgb565, rgb, 0x8D62)
+PixelFormat(, Word4444, Rgba4, rgba, 0x8056)
+PixelFormat(, Word5551, Rgb5a1, rgba, 0x8057)
+PixelFormat(V4, Word8, Rgba8, rgba, 0x8058)
+PixelFormat(, Word2_10x3, A2bgr10, rgba, 0x8059)
+PixelFormat(, Word2_10x3, A2bgr10ui, rgba_integer, 0x906F)
+PixelFormat(V4, Word8, Srgb8a8, rgba, 0x8C43)
+PixelFormat(, Int8, R8i, r_integer, 0x8231)
+PixelFormat(, Word8, R8ui, r_integer, 0x8232)
+PixelFormat(, Int16, R16i, r_integer, 0x8233)
+PixelFormat(, Word16, R16ui, r_integer, 0x8234)
+PixelFormat(, Int32, R32i, r_integer, 0x8235)
+PixelFormat(, Word32, R32ui, r_integer, 0x8236)
+PixelFormat(V2, Int8, Rg8i, rg_integer, 0x8237)
+PixelFormat(V2, Word8, Rg8ui, rg_integer, 0x8238)
+PixelFormat(V2, Int16, Rg16i, rg_integer, 0x8239)
+PixelFormat(V2, Word16, Rg16ui, rg_integer, 0x823A)
+PixelFormat(V2, Int32, Rg32i, rg_integer, 0x823B)
+PixelFormat(V2, Word32, Rg32ui, rg_integer, 0x823C)
+PixelFormat(V4, Int8, Rgba8i, rgba_integer, 0x8D8E)
+PixelFormat(V4, Word8, Rgba8ui, rgba_integer, 0x8D7C)
+PixelFormat(V4, Int16, Rgba16i, rgba_integer, 0x8D88)
+PixelFormat(V4, Word16, Rgba16ui, rgba_integer, 0x8D76)
+PixelFormat(V4, Int32, Rgba32i, rgba_integer, 0x8D82)
+PixelFormat(V4, Word32, Rgba32ui, rgba_integer, 0x8D70)
+
+PixelFormat(, Word16, Depth16, depth_component, 0x81A5)
+PixelFormat(, Word32, Depth24, depth_component, 0x81A6)
+PixelFormat(, Float, Depth32f, depth_component, 0x8CAC)
+PixelFormat(, Word24_8, Depth24Stencil8, depth_stencil, 0x88F0)
+PixelFormat(, FloatWord24_8, Depth32fStencil8, depth_stencil, 0x8CAD)
+--PixelFormat(, Word8, StencilIx8, 0x8D48, 0x1901) -- /GL_OES_texture_stencil8/
+PixelFormat(V2, Word8, Luminance8Alpha8, 0x190A, 0x190A)
+PixelFormat(, Word8, Luminance8, 0x1909, 0x1909)
+PixelFormat(, Word8, Alpha8, 0x1906, 0x1906)
+
+instance InternalFormat a b => ExternalFormat a b where
+	{-# INLINE efmt #-}
+	efmt = ifmt
+
+#define PixelFormat2(_dim, _type, _tag, _format, _internal_fmt) \
+instance ExternalFormat (_dim _type) _tag where \
+	{-# INLINE efmt #-}; \
+	efmt _ = (_format,glType ([] :: [_type]),_internal_fmt) \
+
+PixelFormat2(V4, Word8, Rgb5a1, rgba, 0x8057) -- RGBA W8
+PixelFormat2(V4, Word8, Rgba4, rgba, 0x8056) -- RGBA W8
+PixelFormat2(, Word2_10x3, Rgb5a1, rgba, 0x8057) -- ABGR 2_10_10_10
+PixelFormat2(V4, Float, Rgba16f, rgba, 0x881A) -- RGBA Float
+PixelFormat2(V3, Word8, Rgb565, rgb, 0x8D62) -- RGB W8
+PixelFormat2(V3, HalfFloat, B10fG11fR11f, rgb, 0x8C3A) -- RGB HalfFloat
+PixelFormat2(V3, HalfFloat, E5bgr9, rgb, 0x8C3D) -- RGB HalfFloat
+PixelFormat2(V3, Float, B10fG11fR11f, rgb, 0x8C3A) -- RGB Float
+PixelFormat2(V3, Float, E5bgr9, rgb, 0x8C3D) -- RGB Float
+PixelFormat2(V2, Float, Rg16f, rg, 0x822F) -- RG Float
+PixelFormat2(, Float, R16f, r, 0x822D) -- R Float
+PixelFormat2(, Word32, Depth16, depth_component, 0x81A5) -- D W32
+
+instance ES2Format (V4 Word8) Rgba8 -- (RGBA,UByte)
+instance ES2Format Word4444 Rgba4 -- (RGBA,UShort4444)
+instance ES2Format Word5551 Rgb5a1 -- (RGBA,UShort5551)
+instance ES2Format (V3 Word8) Rgb8 -- (RGB,UByte)
+instance ES2Format Word565 Rgb565 -- (RGB,UShort565)
+instance ES2Format (V2 Word8) Luminance8Alpha8 -- (LUMINANCE_ALPHA,UByte)
+instance ES2Format Word8 Luminance8 -- (LUMINANCE,UByte)
+instance ES2Format Word8 Alpha8 -- (ALPHA,UByte)
+
+
+class ColorRenderable a where
+instance ColorRenderable R8
+instance ColorRenderable Rg8
+instance ColorRenderable Rgb8
+instance ColorRenderable Rgb565
+instance ColorRenderable Rgba4
+instance ColorRenderable Rgb5a1
+instance ColorRenderable Rgba8
+instance ColorRenderable A2bgr10
+instance ColorRenderable A2bgr10ui
+instance ColorRenderable Srgb8a8
+instance ColorRenderable R8i
+instance ColorRenderable R8ui
+instance ColorRenderable R16i
+instance ColorRenderable R16ui
+instance ColorRenderable R32i
+instance ColorRenderable R32ui
+instance ColorRenderable Rg8i
+instance ColorRenderable Rg8ui
+instance ColorRenderable Rg16i
+instance ColorRenderable Rg16ui
+instance ColorRenderable Rg32i
+instance ColorRenderable Rg32ui
+instance ColorRenderable Rgba8i
+instance ColorRenderable Rgba8ui
+instance ColorRenderable Rgba16i
+instance ColorRenderable Rgba16ui
+instance ColorRenderable Rgba32i
+instance ColorRenderable Rgba32ui
+
+class DepthRenderable a where
+instance DepthRenderable Depth16
+instance DepthRenderable Depth24
+instance DepthRenderable Depth32f
+instance DepthRenderable Depth24Stencil8
+instance DepthRenderable Depth32fStencil8
+
+class StencilRenderable a where
+instance StencilRenderable Depth24Stencil8
+instance StencilRenderable Depth32fStencil8
+instance StencilRenderable Stencil8 -- optional
+
+type family SizeOf (f :: *) :: Nat
+type instance SizeOf Float = 4
+type instance SizeOf HalfFloat = 2
+--type instance SizeOf FixedFloat = 4
+type instance SizeOf Word8 = 1
+type instance SizeOf Word16 = 2
+type instance SizeOf Word32 = 4
+type instance SizeOf Int8 = 1
+type instance SizeOf Int16 = 2
+type instance SizeOf Int32 = 4
+type instance SizeOf Int2_10x3 = 4
+type instance SizeOf Word2_10x3 = 4
+type instance SizeOf Word4444 = 2
+type instance SizeOf Word5551 = 2
+type instance SizeOf Word10f11f11f = 4
+type instance SizeOf Word5999 = 4
+type instance SizeOf Word24_8 = 4
+type instance SizeOf FloatWord24_8 = 8
+type instance SizeOf (V2 a) = Aligned (2 * SizeOf a)
+type instance SizeOf (V3 a) = Aligned (3 * SizeOf a)
+type instance SizeOf (V4 a) = Aligned (4 * SizeOf a)
+
+--type family Sum (l :: [Nat]) :: Nat
+--type instance Sum '[] = 0
+--type instance Sum (x ': xs) = x + Sum xs
+
+--type family Map (f :: * -> *) (xs :: [*]) :: [*]
+--type instance Map f '[] = '[]
+--type instance Map f (x ': xs) = f x ': Map f xs
+
+type family Stride (l :: [*]) :: Nat
+type instance Stride '[] = 0
+type instance Stride (x ': xs) = SizeOf x + Stride xs
+
+type family Aligned (x :: Nat) :: Nat
+type instance Aligned x = If (x <=? 3) 4 x
+
+type family If (p :: Bool) (t :: Nat) (f :: Nat) :: Nat
+type instance If True x y = x
+type instance If False x y = y
+
+--type family ImageOf
+--type instance ImageOf Rgba8 = V4 Word8
+--type instance ImageOf Rgba4 = Word16
+--type instance ImageOf Rgba4FromRgba8 = Word16
+
diff --git a/Graphics/OpenGLES/Texture.hs b/Graphics/OpenGLES/Texture.hs
--- a/Graphics/OpenGLES/Texture.hs
+++ b/Graphics/OpenGLES/Texture.hs
@@ -2,10 +2,6 @@
 module Graphics.OpenGLES.Texture (
   -- * Texture
   Texture,
-  --TextureColorFormat,
-  --TextureBitLayout,
-  --TextureInternalFormat,
-  --TextureData,
   glLoadKtx,
   glLoadKtxFile,
 
@@ -41,34 +37,35 @@
 import Graphics.OpenGLES.Base
 import Graphics.OpenGLES.Env
 import Graphics.OpenGLES.Internal
+import Graphics.OpenGLES.PixelFormat
 import Graphics.TextureContainer.KTX
 import Foreign.Ptr (castPtr)
 
 -- glo, target, ktx
-data Texture = Texture GLenum GLO (IORef Ktx)
+data Texture a = Texture GLenum (IORef Ktx) GLO
 -- XXX Texture DoubleBufferring
 
-texSlot :: Word32 -> Texture -> GL ()
-texSlot slot (Texture target glo _) = do
-	tex <- readIORef glo >>= return . fst
-	glActiveTexture (0x84C0 + slot) -- GL_TEXTURE_0 + slot
-	glBindTexture target tex
-
-data TextureColorFormat = ALPHA | RGB | RGBA | LUMINANCE | LUMINANCE_ALPHA
+newtype Texture3D a = Texture3D (Texture a)
+newtype CubeMap a = CubeMap (Texture a)
+newtype Tex2DArray a = Tex2DArray (Texture a)
 
-data TextureBitLayout = UByte | US565 | US444 | US5551
-	-- | ES 3.0
-	| Byte | UShort | Short | UInt | Int | HalfFloat | Float | US4444 | UI2_10_10_10Rev | UI24_8 | UI_10f11f11fRev | UI5999Rev | F32UI24_8Rev
+-- Iso
+--class Tex a where
+--	fromTexture :: Texture b -> a b
+--instance Tex Texture where
+--	fromTexture = id
+--instance Tex Texture3D where
+--	fromTexture = Texture3D
+--instance Tex CubeMap where
+--	fromTexture = CubeMap
+--instance Tex Tex2DArray where
+--	fromTexture = Tex2DArray
 
-data TextureInternalFormat = Alpha | Rgb | Rgba | Luminance | LuminanceAlpha
-	-- 3.0
-	| R8 | R8i | R8ui | R8snorm | R16i | R16ui | R16f | R32i | R32ui | R32f
-	| Rg8 | Rg8i | Rg8ui | Rg8snorm | Rg16i | Rg16ui | Rg16f | Rg32i | Rg32ui | Rg32f
-	| Rgb8 | Rgb8i | Rgb8ui | Rgb8snorm | Rgb16i | Rgb16ui | Rgb16f | Rgb32i | Rgb32ui | Rgb32f
-	| Rgba8 | Rgba8i | Rgba8ui | Rgba8snorm | Rgba16i | Rgba16ui | Rgba16f | Rgba32i | Rgba32ui | Rgba32f
-	| Rgb5a1 | Rgb565 | Rgb9e5 | Rgb10a2 | Rgb10a2ui | Srgb8 | Rgba4 | Srgb8Alpha8
-	| R11fG11fB10f | DepthComponent16 | DepthComponent24 | DepthComponent32
-	| Depth24Stencil8 | Depth32fStencil8
+texSlot :: Word32 -> Texture a -> GL ()
+texSlot slot (Texture target _ glo) = do
+	tex <- getObjId glo
+	glActiveTexture (0x84C0 + slot) -- GL_TEXTURE_0 + slot
+	glBindTexture target tex
 
 data TextureData =
 	  PlainTexture
@@ -82,17 +79,17 @@
 -- | Load a GL Texture object from Ktx texture container.
 -- See <https://github.com/KhronosGroup/KTX/blob/master/lib/loader.c>
 -- TODO: reject 2DArray/3D texture if unsupported
-glLoadKtx :: Maybe Texture -> Ktx -> GL Texture
+glLoadKtx :: Maybe (Texture a) -> Ktx -> GL (Texture a)
 glLoadKtx oldtex ktx@Ktx{..} = do
 	--putStrLn.show $ ktx
 	let newTexture target = case oldtex of
-		Just (Texture _ glo ref) -> do
+		Just (Texture _ ref glo) -> do
 			writeIORef ref ktx
-			readIORef glo >>= glBindTexture target . fst
-			return (Texture target glo ref)
+			glBindTexture target =<< getObjId glo
+			return (Texture target ref glo)
 		Nothing -> Texture target
-			<$> newGLO glGenTextures (glBindTexture target) glDeleteTextures
-			<*> newIORef ktx
+			<$> newIORef ktx
+			<*> newGLO glGenTextures glDeleteTextures (glBindTexture target)
 	case checkKtx ktx of
 		Left msg -> glLog (msg ++ ": " ++ ktxName) >> newTexture 0
 		Right (comp, target, genmip) -> do
@@ -154,7 +151,7 @@
 				void $ showError $ "glGenerateMipmap " ++ ktxName
 			return tex
 
-glLoadKtxFile :: FilePath -> GL Texture
+glLoadKtxFile :: FilePath -> GL (Texture a)
 glLoadKtxFile path = ktxFromFile path >>= glLoadKtx Nothing
 
 -- glPixelStorei(GL_UNPACK_ALIGNMENT, 4)
@@ -245,10 +242,10 @@
 clampToEdge = WrapMode 0x812F
 mirroredRepeat = WrapMode 0x8370
 
-setSampler :: Texture -> Sampler -> GL ()
-setSampler (Texture target glo _) (Sampler (WrapMode s, WrapMode t, r) a
+setSampler :: Texture a -> Sampler -> GL ()
+setSampler (Texture target _ glo) (Sampler (WrapMode s, WrapMode t, r) a
 		(MagFilter g, MinFilter n)) = do
-	tex <- readIORef glo >>= return . fst
+	tex <- getObjId glo
 	glBindTexture target tex
 	glTexParameteri target 0x2802 s
 	glTexParameteri target 0x2803 t
diff --git a/Graphics/OpenGLES/Types.hs b/Graphics/OpenGLES/Types.hs
--- a/Graphics/OpenGLES/Types.hs
+++ b/Graphics/OpenGLES/Types.hs
@@ -22,7 +22,7 @@
   
   -- * Vertex Attribute Array Source Datatypes
   HalfFloat(..), FixedFloat(..),
-  Int10x3_2(..), Word10x3_2(..)
+  Int2_10x3(..), Word2_10x3(..)
   ) where
 import Control.Monad (when)
 import Foreign
diff --git a/opengles.cabal b/opengles.cabal
--- a/opengles.cabal
+++ b/opengles.cabal
@@ -1,5 +1,5 @@
 name:                opengles
-version:             0.4.0
+version:             0.5.0
 synopsis:            OpenGL ES 2.0 and 3.0 with EGL 1.4
 description:         A simplified OpenGL ES core wrapper library.
                      The mission statement of this library is three F: Fun, Fast, yet Flexible.
@@ -8,9 +8,9 @@
                      also works in OpenGL 4.1/4.3+ environment on desktop.
 license:             LGPL-3
 license-file:        LICENSE
-author:              capsjac@gmail.com
-maintainer:          capsjac@gmail.com
--- copyright:           
+author:              capsjac <capsjac at gmail dot com>
+maintainer:          capsjac <capsjac at gmail dot com>
+copyright:           (c) 2014 capsjac
 category:            Graphics
 build-type:          Simple
 extra-source-files:
@@ -35,7 +35,9 @@
     Graphics.OpenGLES.Buffer,
     Graphics.OpenGLES.Core,
     Graphics.OpenGLES.Env,
+    Graphics.OpenGLES.Framebuffer,
     Graphics.OpenGLES.Internal,
+    Graphics.OpenGLES.PixelFormat,
     Graphics.OpenGLES.State,
     Graphics.OpenGLES.Texture,
     Graphics.OpenGLES.Types,
